From 067b69f44992b7dc6dcf30c4071b23a27febfc6b Mon Sep 17 00:00:00 2001 From: Cmdr McDonald Date: Sat, 11 Mar 2017 13:28:24 +0000 Subject: [PATCH] Link in components --- src/app/components/BattleCentre.jsx | 45 ++++++++++----- src/app/components/Cargo.jsx | 12 ++-- src/app/components/Movement.jsx | 85 +++++++++++++++++++++++++++++ src/app/shipyard/Calculations.js | 79 +++++++++++++++++++++++++++ src/app/shipyard/Ship.js | 48 ++++++++++++++++ src/less/app.less | 1 + src/less/movement.less | 26 +++++++++ 7 files changed, 276 insertions(+), 20 deletions(-) create mode 100644 src/app/components/Movement.jsx create mode 100644 src/less/movement.less diff --git a/src/app/components/BattleCentre.jsx b/src/app/components/BattleCentre.jsx index fc6297ea..c5187ff5 100644 --- a/src/app/components/BattleCentre.jsx +++ b/src/app/components/BattleCentre.jsx @@ -5,6 +5,7 @@ import Slider from '../components/Slider'; import Pips from '../components/Pips'; import Fuel from '../components/Fuel'; import Cargo from '../components/Cargo'; +import Movement from '../components/Movement'; import EngagementRange from '../components/EngagementRange'; /** @@ -29,7 +30,23 @@ export default class BattleCentre extends TranslatedComponent { const { ship } = this.props; const opponent = BattleCentre.DEFAULT_OPPONENT; - this.state = { }; + this._cargoUpdated = this._cargoUpdated.bind(this); + this._fuelUpdated = this._fuelUpdated.bind(this); + this._pipsUpdated = this._pipsUpdated.bind(this); + this._engagementRangeUpdated = this._engagementRangeUpdated.bind(this); + + this.state = { + // Pips + sys: 2, + eng: 2, + wep: 2, + // Fuel + fuel: ship.fuelCapacity, + // Cargo + cargo: ship.cargoCapacity, + // Engagement range + engagementRange: 1500, + }; } componentWillReceiveProps(nextProps) { @@ -42,28 +59,28 @@ export default class BattleCentre extends TranslatedComponent { * Triggered when pips have been updated */ _pipsUpdated(sys, eng, wep) { - console.log('Pips are now ' + sys + '/' + eng + '/' + wep); + this.setState({ sys, eng, wep }); } /** * Triggered when fuel has been updated */ _fuelUpdated(fuel) { - console.log('Fuel is now ' + fuel); + this.setState({ fuel }); } /** * Triggered when cargo has been updated */ _cargoUpdated(cargo) { - console.log('Cargo is now ' + cargo); + this.setState({ cargo }); } /** * Triggered when engagement range has been updated */ _engagementRangeUpdated(engagementRange) { - console.log('Engagement range is now ' + engagementRange); + this.setState({ engagementRange }); } /** @@ -73,24 +90,22 @@ export default class BattleCentre extends TranslatedComponent { render() { const { language, onWindowResize, sizeRatio, tooltip, termtip } = this.context; const { formats, translate, units } = language; - const { against, expanded, maxRange, range, totals } = this.state; + const { sys, eng, wep, cargo, fuel, engagementRange, totals } = this.state; const { ship } = this.props; - const shipUpdated = this._shipUpdated; - const pipsUpdated = this._pipsUpdated; - const fuelUpdated = this._fuelUpdated; - const cargoUpdated = this._cargoUpdated; - const engagementRangeUpdated = this._engagementRangeUpdated; return (

{translate('battle centre')}

- +
- - - + + + +
+
+
); diff --git a/src/app/components/Cargo.jsx b/src/app/components/Cargo.jsx index 1e7ddbaf..f03ae01e 100644 --- a/src/app/components/Cargo.jsx +++ b/src/app/components/Cargo.jsx @@ -58,12 +58,14 @@ export default class Cargo extends TranslatedComponent { */ _cargoChange(cargoLevel) { const { cargoCapacity } = this.state; - // We round the cargo level to a suitable value given the capacity - cargoLevel = Math.round(cargoLevel * cargoCapacity) / cargoCapacity; + if (cargoCapacity > 0) { + // We round the cargo level to a suitable value given the capacity + cargoLevel = Math.round(cargoLevel * cargoCapacity) / cargoCapacity; - if (cargoLevel != this.state.cargoLevel) { - this.setState({ cargoLevel }); - this.props.onChange(Math.round(cargoLevel * cargoCapacity)); + if (cargoLevel != this.state.cargoLevel) { + this.setState({ cargoLevel }); + this.props.onChange(Math.round(cargoLevel * cargoCapacity)); + } } } diff --git a/src/app/components/Movement.jsx b/src/app/components/Movement.jsx new file mode 100644 index 00000000..3cf1dc8e --- /dev/null +++ b/src/app/components/Movement.jsx @@ -0,0 +1,85 @@ +import React from 'react'; +import cn from 'classnames'; +import TranslatedComponent from './TranslatedComponent'; + +/** + * Movement + */ +export default class Movement extends TranslatedComponent { + static PropTypes = { + ship: React.PropTypes.object.isRequired, + eng: React.PropTypes.number.isRequired, + fuel: React.PropTypes.number.isRequired, + cargo: React.PropTypes.number.isRequired + }; + + /** + * Constructor + * @param {Object} props React Component properties + */ + constructor(props) { + super(props); + + this._toggleBoost = this._toggleBoost.bind(this); + + this.state = { boost: false }; + } + + /** + * Toggle the boost feature + */ + _toggleBoost() { + let { boost } = this.state; + boost = !boost; + this.setState({ boost }); + } + + /** + * Render movement + * @return {React.Component} contents + */ + render() { + const { ship, eng, cargo, fuel } = this.props; + const { language } = this.context; + const { formats, translate, units } = language; + const { boost } = this.state; + + // + return ( + + + // Axes + + + + // End Arrow + + // Axes arcs and arrows + + + + + + + + + + + + + + + + // Speed + {formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s + // Pitch + {formats.f1(ship.calcPitch(eng, fuel, cargo, boost))}°/s + // Roll + {formats.f1(ship.calcRoll(eng, fuel, cargo, boost))}°/s + // Yaw + {formats.f1(ship.calcYaw(eng, fuel, cargo, boost))}°/s + + + ); + } +} diff --git a/src/app/shipyard/Calculations.js b/src/app/shipyard/Calculations.js index 47b74b7f..e5b56dc0 100644 --- a/src/app/shipyard/Calculations.js +++ b/src/app/shipyard/Calculations.js @@ -173,3 +173,82 @@ function normValues(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, bas res * (1 - (engpip * 1)), res]; } + +function calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, base, engpip, eng) { + 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 ynorm = Math.pow(xnorm, exponent); + const mul = minMul + ynorm * (maxMul - minMul); + const res = base * mul; + + return res * (1 - (engpip * (4 - eng))); +} + +export function calcSpeed(mass, baseSpeed, thrusters, engpip, eng, boostFactor, boost) { + // thrusters might be a module or a template; handle either here + const minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass; + const optMass = thrusters instanceof Module ? thrusters.getOptMass() : thrusters.optmass; + const maxMass = thrusters instanceof Module ? thrusters.getMaxMass() : thrusters.maxmass; + const minMul = thrusters instanceof Module ? thrusters.getMinMul('speed') : (thrusters.minmulspeed ? thrusters.minmulspeed : thrusters.minmul); + const optMul = thrusters instanceof Module ? thrusters.getOptMul('speed') : (thrusters.optmulspeed ? thrusters.minmulspeed : thrusters.minmul); + const maxMul = thrusters instanceof Module ? thrusters.getMaxMul('speed') : (thrusters.maxmulspeed ? thrusters.minmulspeed : thrusters.minmul); + + let result = calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, baseSpeed, engpip, eng); + if (boost == true) { + result *= boostFactor; + } + + return result; +} + +export function calcPitch(mass, basePitch, thrusters, engpip, eng, boostFactor, boost) { + // thrusters might be a module or a template; handle either here + let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass; + let optMass = thrusters instanceof Module ? thrusters.getOptMass() : thrusters.optmass; + let maxMass = thrusters instanceof Module ? thrusters.getMaxMass() : thrusters.maxmass; + let minMul = thrusters instanceof Module ? thrusters.getMinMul('rotation') : (thrusters.minmulrotation ? thrusters.minmulrotation : thrusters.minmul); + let optMul = thrusters instanceof Module ? thrusters.getOptMul('rotation') : (thrusters.optmulrotation ? thrusters.optmulrotation : thrusters.optmul); + let maxMul = thrusters instanceof Module ? thrusters.getMaxMul('rotation') : (thrusters.maxmulrotation ? thrusters.maxmulrotation : thrusters.maxmul); + + let result = calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, basePitch, engpip, eng); + if (boost == true) { + result *= boostFactor; + } + + return result; +} + +export function calcRoll(mass, baseRoll, thrusters, engpip, eng, boostFactor, boost) { + // thrusters might be a module or a template; handle either here + let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass; + let optMass = thrusters instanceof Module ? thrusters.getOptMass() : thrusters.optmass; + let maxMass = thrusters instanceof Module ? thrusters.getMaxMass() : thrusters.maxmass; + let minMul = thrusters instanceof Module ? thrusters.getMinMul('rotation') : (thrusters.minmulrotation ? thrusters.minmulrotation : thrusters.minmul); + let optMul = thrusters instanceof Module ? thrusters.getOptMul('rotation') : (thrusters.optmulrotation ? thrusters.optmulrotation : thrusters.optmul); + let maxMul = thrusters instanceof Module ? thrusters.getMaxMul('rotation') : (thrusters.maxmulrotation ? thrusters.maxmulrotation : thrusters.maxmul); + + let result = calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, baseRoll, engpip, eng); + if (boost == true) { + result *= boostFactor; + } + + return result; +} + +export function calcYaw(mass, baseYaw, thrusters, engpip, eng, boostFactor, boost) { + // thrusters might be a module or a template; handle either here + let minMass = thrusters instanceof Module ? thrusters.getMinMass() : thrusters.minmass; + let optMass = thrusters instanceof Module ? thrusters.getOptMass() : thrusters.optmass; + let maxMass = thrusters instanceof Module ? thrusters.getMaxMass() : thrusters.maxmass; + let minMul = thrusters instanceof Module ? thrusters.getMinMul('rotation') : (thrusters.minmulrotation ? thrusters.minmulrotation : thrusters.minmul); + let optMul = thrusters instanceof Module ? thrusters.getOptMul('rotation') : (thrusters.optmulrotation ? thrusters.optmulrotation : thrusters.optmul); + let maxMul = thrusters instanceof Module ? thrusters.getMaxMul('rotation') : (thrusters.maxmulrotation ? thrusters.maxmulrotation : thrusters.maxmul); + + let result = calcValue(minMass, optMass, maxMass, minMul, optMul, maxMul, mass, baseYaw, engpip, eng); + if (boost == true) { + result *= boostFactor; + } + + return result; +} + diff --git a/src/app/shipyard/Ship.js b/src/app/shipyard/Ship.js index 2370a295..a9b99652 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -194,6 +194,54 @@ export default class Ship { return Calc.speed(this.unladenMass + fuel + cargo, this.speed, this.standard[1].m, this.pipSpeed); } + /** + * Calculate the speed for a given configuration + * @param {Number} eng Number of pips in ENG + * @param {Number} fuel Amount of fuel carried + * @param {Number} cargo Amount of cargo carried + * @param {boolean} boost true if boost is applied + * @return {Number} Speed + */ + calcSpeed(eng, fuel, cargo, boost) { + return Calc.calcSpeed(this.unladenMass + fuel + cargo, this.speed, this.standard[1].m, this.pipSpeed, eng, this.topBoost / this.topSpeed, boost); + } + + /** + * Calculate the pitch for a given configuration + * @param {Number} eng Number of pips in ENG + * @param {Number} fuel Amount of fuel carried + * @param {Number} cargo Amount of cargo carried + * @param {boolean} boost true if boost is applied + * @return {Number} Pitch + */ + calcPitch(eng, fuel, cargo, boost) { + return Calc.calcPitch(this.unladenMass + fuel + cargo, this.pitch, this.standard[1].m, this.pipSpeed, eng, this.topBoost / this.topSpeed, boost); + } + + /** + * Calculate the roll for a given configuration + * @param {Number} eng Number of pips in ENG + * @param {Number} fuel Amount of fuel carried + * @param {Number} cargo Amount of cargo carried + * @param {boolean} boost true if boost is applied + * @return {Number} Roll + */ + calcRoll(eng, fuel, cargo, boost) { + return Calc.calcRoll(this.unladenMass + fuel + cargo, this.roll, this.standard[1].m, this.pipSpeed, eng, this.topBoost / this.topSpeed, boost); + } + + /** + * Calculate the yaw for a given configuration + * @param {Number} eng Number of pips in ENG + * @param {Number} fuel Amount of fuel carried + * @param {Number} cargo Amount of cargo carried + * @param {boolean} boost true if boost is applied + * @return {Number} Yaw + */ + calcYaw(eng, fuel, cargo, boost) { + return Calc.calcYaw(this.unladenMass + fuel + cargo, this.yaw, this.standard[1].m, this.pipSpeed, eng, this.topBoost / this.topSpeed, boost); + } + /** * Calculate the recovery time after losing or turning on shields * Thanks to CMDRs Al Gray, GIF, and Nomad Enigma for providing Shield recharge data and formulas diff --git a/src/less/app.less b/src/less/app.less index 303a3468..2dceb253 100755 --- a/src/less/app.less +++ b/src/less/app.less @@ -20,6 +20,7 @@ @import 'sortable'; @import 'loader'; @import 'pips'; +@import 'movement'; html, body { height: 100%; diff --git a/src/less/movement.less b/src/less/movement.less new file mode 100644 index 00000000..bfd43bac --- /dev/null +++ b/src/less/movement.less @@ -0,0 +1,26 @@ + +#movement { + svg { + width: 100%; + height: 100%; + stroke: @primary-disabled; + fill: @primary-disabled; + + text { + stroke: @primary; + } + } + + button { + font-size: 1.4em; + background: @primary-bg; + color: @primary; + border: 1px solid @primary; + &.boost { + // Shown when boost is enabled + background: @primary; + color: @primary-bg; + } + } + +}