mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-10 07:05:35 +00:00
Start of shields component
This commit is contained in:
BIN
src/app/components/.AvailableModulesMenu.jsx.swp
Normal file
BIN
src/app/components/.AvailableModulesMenu.jsx.swp
Normal file
Binary file not shown.
BIN
src/app/components/.BattleCentre.jsx.swp
Normal file
BIN
src/app/components/.BattleCentre.jsx.swp
Normal file
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
import Ship from '../shipyard/Ship';
|
||||||
import { Ships } from 'coriolis-data/dist';
|
import { Ships } from 'coriolis-data/dist';
|
||||||
import Slider from './Slider';
|
import Slider from './Slider';
|
||||||
import Pips from './Pips';
|
import Pips from './Pips';
|
||||||
@@ -8,6 +9,7 @@ import Cargo from './Cargo';
|
|||||||
import Movement from './Movement';
|
import Movement from './Movement';
|
||||||
import EngagementRange from './EngagementRange';
|
import EngagementRange from './EngagementRange';
|
||||||
import ShipPicker from './ShipPicker';
|
import ShipPicker from './ShipPicker';
|
||||||
|
import Shields from './Shields';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Battle centre allows you to pit your current build against another ship,
|
* Battle centre allows you to pit your current build against another ship,
|
||||||
@@ -27,26 +29,29 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const { ship } = this.props;
|
const { ship } = this.props;
|
||||||
const opponent = BattleCentre.DEFAULT_OPPONENT;
|
|
||||||
|
|
||||||
this._cargoUpdated = this._cargoUpdated.bind(this);
|
this._cargoUpdated = this._cargoUpdated.bind(this);
|
||||||
this._fuelUpdated = this._fuelUpdated.bind(this);
|
this._fuelUpdated = this._fuelUpdated.bind(this);
|
||||||
this._pipsUpdated = this._pipsUpdated.bind(this);
|
this._pipsUpdated = this._pipsUpdated.bind(this);
|
||||||
this._engagementRangeUpdated = this._engagementRangeUpdated.bind(this);
|
this._engagementRangeUpdated = this._engagementRangeUpdated.bind(this);
|
||||||
this._targetShipUpdated = this._targetShipUpdated.bind(this);
|
this._opponentUpdated = this._opponentUpdated.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
// Pips
|
|
||||||
sys: 2,
|
sys: 2,
|
||||||
eng: 2,
|
eng: 2,
|
||||||
wep: 2,
|
wep: 2,
|
||||||
fuel: ship.fuelCapacity,
|
fuel: ship.fuelCapacity,
|
||||||
cargo: ship.cargoCapacity,
|
cargo: ship.cargoCapacity,
|
||||||
engagementRange: 1500,
|
engagementRange: 1500,
|
||||||
targetShip: Ships['anaconda']
|
opponent: new Ship('anaconda', Ships['anaconda'].properties, Ships['anaconda'].slots)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update state based on property and context changes
|
||||||
|
* @param {Object} nextProps Incoming/Next properties
|
||||||
|
* @returns {boolean} true if an update is required
|
||||||
|
*/
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
// Rather than try to keep track of what changes our children require we force an update and let them work it out
|
// Rather than try to keep track of what changes our children require we force an update and let them work it out
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
@@ -55,6 +60,9 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when pips have been updated
|
* Triggered when pips have been updated
|
||||||
|
* @param {number} sys SYS pips
|
||||||
|
* @param {number} eng ENG pips
|
||||||
|
* @param {number} wep WEP pips
|
||||||
*/
|
*/
|
||||||
_pipsUpdated(sys, eng, wep) {
|
_pipsUpdated(sys, eng, wep) {
|
||||||
this.setState({ sys, eng, wep });
|
this.setState({ sys, eng, wep });
|
||||||
@@ -62,6 +70,7 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when fuel has been updated
|
* Triggered when fuel has been updated
|
||||||
|
* @param {number} fuel the amount of fuel, in T
|
||||||
*/
|
*/
|
||||||
_fuelUpdated(fuel) {
|
_fuelUpdated(fuel) {
|
||||||
this.setState({ fuel });
|
this.setState({ fuel });
|
||||||
@@ -69,6 +78,7 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when cargo has been updated
|
* Triggered when cargo has been updated
|
||||||
|
* @param {number} cargo the amount of cargo, in T
|
||||||
*/
|
*/
|
||||||
_cargoUpdated(cargo) {
|
_cargoUpdated(cargo) {
|
||||||
this.setState({ cargo });
|
this.setState({ cargo });
|
||||||
@@ -76,6 +86,7 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when engagement range has been updated
|
* Triggered when engagement range has been updated
|
||||||
|
* @param {number} engagementRange the engagement range, in m
|
||||||
*/
|
*/
|
||||||
_engagementRangeUpdated(engagementRange) {
|
_engagementRangeUpdated(engagementRange) {
|
||||||
this.setState({ engagementRange });
|
this.setState({ engagementRange });
|
||||||
@@ -83,9 +94,11 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered when target ship has been updated
|
* Triggered when target ship has been updated
|
||||||
|
* @param {object} opponent the opponent's ship
|
||||||
|
* @param {string} opponentBuild the name of the opponent's build
|
||||||
*/
|
*/
|
||||||
_targetShipUpdated(targetShip, targetBuild) {
|
_opponentUpdated(opponent, opponentBuild) {
|
||||||
this.setState({ targetShip, targetBuild: targetBuild });
|
this.setState({ opponent, opponentBuild });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,13 +108,17 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
render() {
|
render() {
|
||||||
const { language, onWindowResize, sizeRatio, tooltip, termtip } = this.context;
|
const { language, onWindowResize, sizeRatio, tooltip, termtip } = this.context;
|
||||||
const { formats, translate, units } = language;
|
const { formats, translate, units } = language;
|
||||||
const { sys, eng, wep, cargo, fuel, engagementRange } = this.state;
|
const { sys, eng, wep, cargo, fuel, engagementRange, opponent } = this.state;
|
||||||
const { ship } = this.props;
|
const { ship } = this.props;
|
||||||
|
|
||||||
|
// Markers are used to propagate state changes
|
||||||
|
const movementMarker = '' + ship.topSpeed + ':' + ship.pitch + ':' + ship.roll + ':' + ship.yaw;
|
||||||
|
const shieldMarker = '' + ship.shield + ':' + ship.cells + ':' + ship.shieldExplRes + ':' + ship.shieldKinRes + ':' + ship.shieldThermRes;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<h1>{translate('battle centre')}</h1>
|
<h1>{translate('battle centre')}</h1>
|
||||||
<ShipPicker onChange={this._targetShipUpdated}/>
|
<ShipPicker onChange={this._opponentUpdated}/>
|
||||||
<div className='group third'>
|
<div className='group third'>
|
||||||
<Pips ship={ship} onChange={this._pipsUpdated}/>
|
<Pips ship={ship} onChange={this._pipsUpdated}/>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,7 +128,10 @@ export default class BattleCentre extends TranslatedComponent {
|
|||||||
<EngagementRange ship={ship} onChange={this._engagementRangeUpdated}/>
|
<EngagementRange ship={ship} onChange={this._engagementRangeUpdated}/>
|
||||||
</div>
|
</div>
|
||||||
<div className='group third'>
|
<div className='group third'>
|
||||||
<Movement ship={ship} eng={eng} cargo={cargo} fuel={fuel}/>
|
<Shields marker={shieldMarker} ship={ship} opponent={opponent} sys={sys}/>
|
||||||
|
</div>
|
||||||
|
<div className='group third'>
|
||||||
|
<Movement marker={movementMarker} ship={ship} eng={eng} cargo={cargo} fuel={fuel}/>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default class Cargo extends TranslatedComponent {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
cargoCapacity: ship.cargoCapacity,
|
cargoCapacity: ship.cargoCapacity,
|
||||||
cargoLevel: 1,
|
cargoLevel: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default class Range extends TranslatedComponent {
|
|||||||
const maxRange = this._calcMaxRange(ship);
|
const maxRange = this._calcMaxRange(ship);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
maxRange: maxRange,
|
maxRange,
|
||||||
rangeLevel: 1,
|
rangeLevel: 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ export default class Range extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update range
|
* Update range
|
||||||
* @param {number} range percentage level from 0 to 1
|
* @param {number} rangeLevel percentage level from 0 to 1
|
||||||
*/
|
*/
|
||||||
_rangeChange(rangeLevel) {
|
_rangeChange(rangeLevel) {
|
||||||
const { maxRange } = this.state;
|
const { maxRange } = this.state;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import TranslatedComponent from './TranslatedComponent';
|
|||||||
*/
|
*/
|
||||||
export default class Movement extends TranslatedComponent {
|
export default class Movement extends TranslatedComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
marker: React.PropTypes.string.isRequired,
|
||||||
ship: React.PropTypes.object.isRequired,
|
ship: React.PropTypes.object.isRequired,
|
||||||
eng: React.PropTypes.number.isRequired,
|
eng: React.PropTypes.number.isRequired,
|
||||||
fuel: React.PropTypes.number.isRequired,
|
fuel: React.PropTypes.number.isRequired,
|
||||||
@@ -44,7 +45,6 @@ export default class Movement extends TranslatedComponent {
|
|||||||
const { formats, translate, units } = language;
|
const { formats, translate, units } = language;
|
||||||
const { boost } = this.state;
|
const { boost } = this.state;
|
||||||
|
|
||||||
//<svg style={{ width: '100%', height: '100%', stroke: '#FF8C0D', fill: '#FF8C0D' }} viewBox='0 0 600 600' fillRule="evenodd" clipRule="evenodd">
|
|
||||||
return (
|
return (
|
||||||
<span id='movement'>
|
<span id='movement'>
|
||||||
<svg viewBox='0 0 600 600' fillRule="evenodd" clipRule="evenodd">
|
<svg viewBox='0 0 600 600' fillRule="evenodd" clipRule="evenodd">
|
||||||
@@ -73,13 +73,13 @@ export default class Movement extends TranslatedComponent {
|
|||||||
// Speed
|
// Speed
|
||||||
<text x="500" y="80" strokeWidth='1'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text>
|
<text x="500" y="80" strokeWidth='1'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text>
|
||||||
// Pitch
|
// Pitch
|
||||||
<text x="355" y="410" strokeWidth='1'>{formats.f1(ship.calcPitch(eng, fuel, cargo, boost))}°/s</text>
|
<text x="355" y="410" strokeWidth='1'>{formats.int(ship.calcPitch(eng, fuel, cargo, boost))}°/s</text>
|
||||||
// Roll
|
// Roll
|
||||||
<text x="450" y="100" strokeWidth='1'>{formats.f1(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text>
|
<text x="450" y="100" strokeWidth='1'>{formats.int(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text>
|
||||||
// Yaw
|
// Yaw
|
||||||
<text x="160" y="430" strokeWidth='1'>{formats.f1(ship.calcYaw(eng, fuel, cargo, boost))}°/s</text>
|
<text x="160" y="430" strokeWidth='1'>{formats.int(ship.calcYaw(eng, fuel, cargo, boost))}°/s</text>
|
||||||
</svg>
|
</svg>
|
||||||
<button className={boost ? 'boost' : 'noboost'} onClick={this._toggleBoost}>Boost</button>
|
{ ship.canBoost() ? <button className={boost ? 'boost' : 'noboost'} onClick={this._toggleBoost}>Boost</button> : null }
|
||||||
</span>);
|
</span>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ export default class Pips extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a click
|
* Handle a click
|
||||||
|
* @param {string} which Which item was clicked
|
||||||
*/
|
*/
|
||||||
onClick(which) {
|
onClick(which) {
|
||||||
if (which == 'SYS') {
|
if (which == 'SYS') {
|
||||||
|
|||||||
194
src/app/components/Shields.jsx
Normal file
194
src/app/components/Shields.jsx
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import cn from 'classnames';
|
||||||
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
|
import * as Calc from '../shipyard/Calculations';
|
||||||
|
import { DamageAbsolute, DamageExplosive, DamageKinetic, DamageThermal } from './SvgIcons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shields
|
||||||
|
* Effective shield strength (including SCBs)
|
||||||
|
* Time for opponent to down shields
|
||||||
|
* - need sustained DPS for each type of damage (K/T/E/R)
|
||||||
|
* - turn in to % of shields removed per second
|
||||||
|
*/
|
||||||
|
export default class Shields extends TranslatedComponent {
|
||||||
|
static propTypes = {
|
||||||
|
marker: React.PropTypes.string.isRequired,
|
||||||
|
ship: React.PropTypes.object.isRequired,
|
||||||
|
opponent: React.PropTypes.object.isRequired,
|
||||||
|
sys: React.PropTypes.number.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param {Object} props React Component properties
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
const { shield, absolute, explosive, kinetic, thermal } = this._calcMetrics(props.ship, props.opponent, props.sys);
|
||||||
|
this.state = { shield, absolute, explosive, kinetic, thermal };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the state if our properties change
|
||||||
|
* @param {Object} nextProps Incoming/Next properties
|
||||||
|
* @return {boolean} Returns true if the component should be rerendered
|
||||||
|
*/
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (this.props.marker != nextProps.marker || this.props.sys != nextProps.sys) {
|
||||||
|
const { shield, absolute, explosive, kinetic, thermal } = this._calcMetrics(nextProps.ship, nextProps.opponent, nextProps.sys);
|
||||||
|
this.setState({ shield, absolute, explosive, kinetic, thermal });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate shield metrics
|
||||||
|
* @param {Object} ship The ship
|
||||||
|
* @param {Object} opponent The opponent ship
|
||||||
|
* @param {int} sys The opponent ship
|
||||||
|
* @returns {Object} Shield metrics
|
||||||
|
*/
|
||||||
|
_calcMetrics(ship, opponent, sys) {
|
||||||
|
const sysResistance = this._calcSysResistance(sys);
|
||||||
|
|
||||||
|
const shieldGenerator = ship.findShieldGenerator();
|
||||||
|
|
||||||
|
// Boosters
|
||||||
|
let boost = 1;
|
||||||
|
let boosterExplDmg = 1;
|
||||||
|
let boosterKinDmg = 1;
|
||||||
|
let boosterThermDmg = 1;
|
||||||
|
for (let slot of ship.hardpoints) {
|
||||||
|
if (slot.enabled && slot.m && slot.m.grp == 'sb') {
|
||||||
|
boost += slot.m.getShieldBoost();
|
||||||
|
boosterExplDmg = boosterExplDmg * (1 - slot.m.getExplosiveResistance());
|
||||||
|
boosterKinDmg = boosterKinDmg * (1 - slot.m.getKineticResistance());
|
||||||
|
boosterThermDmg = boosterThermDmg * (1 - slot.m.getThermalResistance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate diminishing returns for boosters
|
||||||
|
boost = Math.min(boost, (1 - Math.pow(Math.E, -0.7 * boost)) * 2.5);
|
||||||
|
// Remove base shield generator strength
|
||||||
|
boost -= 1;
|
||||||
|
boosterExplDmg = boosterExplDmg > 0.7 ? boosterExplDmg : 0.7 - (0.7 - boosterExplDmg) / 2;
|
||||||
|
boosterKinDmg = boosterKinDmg > 0.7 ? boosterExplDmg : 0.7 - (0.7 - boosterKinDmg) / 2;
|
||||||
|
boosterThermDmg = boosterThermDmg > 0.7 ? boosterExplDmg : 0.7 - (0.7 - boosterThermDmg) / 2;
|
||||||
|
|
||||||
|
const generatorStrength = Calc.shieldStrength(ship.hullMass, ship.baseShieldStrength, shieldGenerator, 1);
|
||||||
|
const boostersStrength = generatorStrength * boost;
|
||||||
|
const shield = {
|
||||||
|
generator: generatorStrength,
|
||||||
|
boosters: boostersStrength,
|
||||||
|
total: generatorStrength + boostersStrength
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resistances have three components: the shield generator, the shield boosters and the SYS pips.
|
||||||
|
// We re-cast these as damage percentages
|
||||||
|
const absolute = {
|
||||||
|
generator: 1,
|
||||||
|
boosters: 1,
|
||||||
|
sys: 1 - sysResistance,
|
||||||
|
total: 1 - sysResistance
|
||||||
|
};
|
||||||
|
|
||||||
|
const explosive = {
|
||||||
|
generator: 1 - shieldGenerator.getExplosiveResistance(),
|
||||||
|
boosters: boosterExplDmg,
|
||||||
|
sys: (1 - sysResistance),
|
||||||
|
total: (1 - shieldGenerator.getExplosiveResistance()) * boosterExplDmg * (1 - sysResistance)
|
||||||
|
};
|
||||||
|
|
||||||
|
const kinetic = {
|
||||||
|
generator: 1 - shieldGenerator.getKineticResistance(),
|
||||||
|
boosters: boosterKinDmg,
|
||||||
|
sys: (1 - sysResistance),
|
||||||
|
total: (1 - shieldGenerator.getKineticResistance()) * boosterKinDmg * (1 - sysResistance)
|
||||||
|
};
|
||||||
|
|
||||||
|
const thermal = {
|
||||||
|
generator: 1 - shieldGenerator.getThermalResistance(),
|
||||||
|
boosters: boosterThermDmg,
|
||||||
|
sys: (1 - sysResistance),
|
||||||
|
total: (1 - shieldGenerator.getThermalResistance()) * boosterThermDmg * (1 - sysResistance)
|
||||||
|
};
|
||||||
|
|
||||||
|
return { shield, absolute, explosive, kinetic, thermal };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the resistance provided by SYS pips
|
||||||
|
* @param {integer} sys the value of the SYS pips
|
||||||
|
* @returns {integer} the resistance for the given pips
|
||||||
|
*/
|
||||||
|
_calcSysResistance(sys) {
|
||||||
|
return Math.pow(sys,0.85) * 0.6 / Math.pow(4,0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render shields
|
||||||
|
* @return {React.Component} contents
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { ship, sys } = this.props;
|
||||||
|
const { language, tooltip, termtip } = this.context;
|
||||||
|
const { formats, translate, units } = language;
|
||||||
|
const { shield, absolute, explosive, kinetic, thermal } = this.state;
|
||||||
|
|
||||||
|
const shieldTooltipDetails = [];
|
||||||
|
shieldTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.int(shield.generator)}{units.MJ}</div>);
|
||||||
|
shieldTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.int(shield.boosters)}{units.MJ}</div>);
|
||||||
|
|
||||||
|
const absoluteTooltipDetails = [];
|
||||||
|
absoluteTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(absolute.generator)}</div>);
|
||||||
|
absoluteTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(absolute.boosters)}</div>);
|
||||||
|
absoluteTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(absolute.sys)}</div>);
|
||||||
|
|
||||||
|
const explosiveTooltipDetails = [];
|
||||||
|
explosiveTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(explosive.generator)}</div>);
|
||||||
|
explosiveTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(explosive.boosters)}</div>);
|
||||||
|
explosiveTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(explosive.sys)}</div>);
|
||||||
|
|
||||||
|
const kineticTooltipDetails = [];
|
||||||
|
kineticTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(kinetic.generator)}</div>);
|
||||||
|
kineticTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(kinetic.boosters)}</div>);
|
||||||
|
kineticTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(kinetic.sys)}</div>);
|
||||||
|
|
||||||
|
const thermalTooltipDetails = [];
|
||||||
|
thermalTooltipDetails.push(<div key='generator'>{translate('generator') + ' ' + formats.pct1(thermal.generator)}</div>);
|
||||||
|
thermalTooltipDetails.push(<div key='boosters'>{translate('boosters') + ' ' + formats.pct1(thermal.boosters)}</div>);
|
||||||
|
thermalTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(thermal.sys)}</div>);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span id='shields'>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan='5' onMouseOver={termtip.bind(null, <div>{shieldTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('shields')}: {formats.int(shield.total)}{units.MJ}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className='le'>{translate('damage from')}</td>
|
||||||
|
<td className='ri'>
|
||||||
|
<span onMouseOver={termtip.bind(null, 'absolute')} onMouseOut={tooltip.bind(null, null)}><DamageAbsolute /></span>
|
||||||
|
<span onMouseOver={termtip.bind(null, <div>{absoluteTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(absolute.total)}</span>
|
||||||
|
</td>
|
||||||
|
<td className='ri'>
|
||||||
|
<span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span>
|
||||||
|
<span onMouseOver={termtip.bind(null, <div>{explosiveTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(explosive.total)}</span>
|
||||||
|
</td>
|
||||||
|
<td className='ri'>
|
||||||
|
<span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span>
|
||||||
|
<span onMouseOver={termtip.bind(null, <div>{kineticTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(kinetic.total)}</span>
|
||||||
|
</td>
|
||||||
|
<td className='ri'>
|
||||||
|
<span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span>
|
||||||
|
<span onMouseOver={termtip.bind(null, <div>{thermalTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(thermal.total)}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</span>);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,7 +56,8 @@ export default class ShipPicker extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update ship
|
* Update ship
|
||||||
* @param {object} ship the ship
|
* @param {object} shipId the ship
|
||||||
|
* @param {string} build the build, if present
|
||||||
*/
|
*/
|
||||||
_shipChange(shipId, build) {
|
_shipChange(shipId, build) {
|
||||||
const ship = new Ship(shipId, Ships[shipId].properties, Ships[shipId].slots);
|
const ship = new Ship(shipId, Ships[shipId].properties, Ships[shipId].slots);
|
||||||
@@ -71,6 +72,7 @@ export default class ShipPicker extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the menu for the picker
|
* Render the menu for the picker
|
||||||
|
* @returns {object} the picker menu
|
||||||
*/
|
*/
|
||||||
_renderPickerMenu() {
|
_renderPickerMenu() {
|
||||||
const { ship, build } = this.state;
|
const { ship, build } = this.state;
|
||||||
|
|||||||
@@ -174,6 +174,20 @@ function normValues(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, bas
|
|||||||
res];
|
res];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a single value
|
||||||
|
* @param {number} minMass the minimum mass of the thrusters
|
||||||
|
* @param {number} optMass the optimum mass of the thrusters
|
||||||
|
* @param {number} maxMass the maximum mass of the thrusters
|
||||||
|
* @param {number} minMul the minimum multiplier of the thrusters
|
||||||
|
* @param {number} optMul the optimum multiplier of the thrusters
|
||||||
|
* @param {number} maxMul the maximum multiplier of the thrusters
|
||||||
|
* @param {number} mass the mass of the ship
|
||||||
|
* @param {base} base the base value from which to calculate
|
||||||
|
* @param {number} engpip the multiplier per pip to engines
|
||||||
|
* @param {number} eng the pips to engines
|
||||||
|
* @returns {number} the resultant value
|
||||||
|
*/
|
||||||
function calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, base, engpip, eng) {
|
function calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, base, engpip, eng) {
|
||||||
const xnorm = Math.min(1, (maxMass - mass) / (maxMass - minMass));
|
const xnorm = Math.min(1, (maxMass - mass) / (maxMass - minMass));
|
||||||
const exponent = Math.log((optMul - minMul) / (maxMul - minMul)) / Math.log(Math.min(1, (maxMass - optMass) / (maxMass - minMass)));
|
const exponent = Math.log((optMul - minMul) / (maxMul - minMul)) / Math.log(Math.min(1, (maxMass - optMass) / (maxMass - minMass)));
|
||||||
@@ -184,6 +198,17 @@ function calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, base
|
|||||||
return res * (1 - (engpip * (4 - eng)));
|
return res * (1 - (engpip * (4 - eng)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate speed for a given setup
|
||||||
|
* @param {number} mass the mass of the ship
|
||||||
|
* @param {number} baseSpeed the base speed of the ship
|
||||||
|
* @param {ojbect} thrusters the thrusters of the ship
|
||||||
|
* @param {number} engpip the multiplier per pip to engines
|
||||||
|
* @param {number} eng the pips to engines
|
||||||
|
* @param {number} boostFactor the boost factor for ths ship
|
||||||
|
* @param {boolean} boost true if the boost is activated
|
||||||
|
* @returns {number} the resultant speed
|
||||||
|
*/
|
||||||
export function calcSpeed(mass, baseSpeed, thrusters, engpip, eng, boostFactor, boost) {
|
export function calcSpeed(mass, baseSpeed, thrusters, engpip, eng, boostFactor, boost) {
|
||||||
// thrusters might be a module or a template; handle either here
|
// thrusters might be a module or a template; handle either here
|
||||||
const minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
const minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
||||||
@@ -201,6 +226,17 @@ export function calcSpeed(mass, baseSpeed, thrusters, engpip, eng, boostFactor,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate pitch for a given setup
|
||||||
|
* @param {number} mass the mass of the ship
|
||||||
|
* @param {number} basePitch the base pitch of the ship
|
||||||
|
* @param {ojbect} thrusters the thrusters of the ship
|
||||||
|
* @param {number} engpip the multiplier per pip to engines
|
||||||
|
* @param {number} eng the pips to engines
|
||||||
|
* @param {number} boostFactor the boost factor for ths ship
|
||||||
|
* @param {boolean} boost true if the boost is activated
|
||||||
|
* @returns {number} the resultant pitch
|
||||||
|
*/
|
||||||
export function calcPitch(mass, basePitch, thrusters, engpip, eng, boostFactor, boost) {
|
export function calcPitch(mass, basePitch, thrusters, engpip, eng, boostFactor, boost) {
|
||||||
// thrusters might be a module or a template; handle either here
|
// thrusters might be a module or a template; handle either here
|
||||||
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
||||||
@@ -218,6 +254,17 @@ export function calcPitch(mass, basePitch, thrusters, engpip, eng, boostFactor,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate roll for a given setup
|
||||||
|
* @param {number} mass the mass of the ship
|
||||||
|
* @param {number} baseRoll the base roll of the ship
|
||||||
|
* @param {ojbect} thrusters the thrusters of the ship
|
||||||
|
* @param {number} engpip the multiplier per pip to engines
|
||||||
|
* @param {number} eng the pips to engines
|
||||||
|
* @param {number} boostFactor the boost factor for ths ship
|
||||||
|
* @param {boolean} boost true if the boost is activated
|
||||||
|
* @returns {number} the resultant roll
|
||||||
|
*/
|
||||||
export function calcRoll(mass, baseRoll, thrusters, engpip, eng, boostFactor, boost) {
|
export function calcRoll(mass, baseRoll, thrusters, engpip, eng, boostFactor, boost) {
|
||||||
// thrusters might be a module or a template; handle either here
|
// thrusters might be a module or a template; handle either here
|
||||||
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
||||||
@@ -235,6 +282,17 @@ export function calcRoll(mass, baseRoll, thrusters, engpip, eng, boostFactor, bo
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate yaw for a given setup
|
||||||
|
* @param {number} mass the mass of the ship
|
||||||
|
* @param {number} baseYaw the base yaw of the ship
|
||||||
|
* @param {ojbect} thrusters the thrusters of the ship
|
||||||
|
* @param {number} engpip the multiplier per pip to engines
|
||||||
|
* @param {number} eng the pips to engines
|
||||||
|
* @param {number} boostFactor the boost factor for ths ship
|
||||||
|
* @param {boolean} boost true if the boost is activated
|
||||||
|
* @returns {number} the resultant yaw
|
||||||
|
*/
|
||||||
export function calcYaw(mass, baseYaw, thrusters, engpip, eng, boostFactor, boost) {
|
export function calcYaw(mass, baseYaw, thrusters, engpip, eng, boostFactor, boost) {
|
||||||
// thrusters might be a module or a template; handle either here
|
// thrusters might be a module or a template; handle either here
|
||||||
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass;
|
||||||
|
|||||||
@@ -1286,13 +1286,13 @@ export default class Ship {
|
|||||||
shield = Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sgSlot.m, 1);
|
shield = Calc.shieldStrength(this.hullMass, this.baseShieldStrength, sgSlot.m, 1);
|
||||||
shieldExplRes = 1 - sgSlot.m.getExplosiveResistance();
|
shieldExplRes = 1 - sgSlot.m.getExplosiveResistance();
|
||||||
shieldExplDRStart = shieldExplRes * 0.7;
|
shieldExplDRStart = shieldExplRes * 0.7;
|
||||||
shieldExplDREnd = shieldExplRes * 0; // Currently don't know where this is
|
shieldExplDREnd = 0;
|
||||||
shieldKinRes = 1 - sgSlot.m.getKineticResistance();
|
shieldKinRes = 1 - sgSlot.m.getKineticResistance();
|
||||||
shieldKinDRStart = shieldKinRes * 0.7;
|
shieldKinDRStart = shieldKinRes * 0.7;
|
||||||
shieldKinDREnd = shieldKinRes * 0; // Currently don't know where this is
|
shieldKinDREnd = 0;
|
||||||
shieldThermRes = 1 - sgSlot.m.getThermalResistance();
|
shieldThermRes = 1 - sgSlot.m.getThermalResistance();
|
||||||
shieldThermDRStart = shieldThermRes * 0.7;
|
shieldThermDRStart = shieldThermRes * 0.7;
|
||||||
shieldThermDREnd = shieldThermRes * 0; // Currently don't know where this is
|
shieldThermDREnd = 0;
|
||||||
|
|
||||||
// Shield from boosters
|
// Shield from boosters
|
||||||
for (let slot of this.hardpoints) {
|
for (let slot of this.hardpoints) {
|
||||||
|
|||||||
Reference in New Issue
Block a user