diff --git a/src/app/components/Modification.jsx b/src/app/components/Modification.jsx index d23e3a52..1ca29bef 100644 --- a/src/app/components/Modification.jsx +++ b/src/app/components/Modification.jsx @@ -59,9 +59,9 @@ export default class Modification extends TranslatedComponent { /** * Triggered when an update to slider value is finished i.e. when losing focus - * - * pnellesen (24/05/2018): added value check below - this should prevent experimental effects from being recalculated - * with each onBlur event, even when no change has actually been made to the field. + * + * pnellesen (24/05/2018): added value check below - this should prevent experimental effects from being recalculated + * with each onBlur event, even when no change has actually been made to the field. */ _updateFinished() { if (this.props.value != this.state.value) { @@ -76,6 +76,7 @@ export default class Modification extends TranslatedComponent { */ render() { let translate = this.context.language.translate; + let formats = this.context.language.formats; let { m, name } = this.props; if (name === 'damagedist') { @@ -96,7 +97,34 @@ export default class Modification extends TranslatedComponent { return (
this.props.modItems[name] = modItem }>
{translate(name, m.grp)}{symbol}
- + + + + + + + +
+ {/* thermload doesn't have any values set therefore we ignore it */} +
{this.props.name !== 'thermload' && + this.props.m.formatModifiedValue( + this.props.name, + this.context.language + ) + }
+
+ {this.props.editable ? + : +
+ +
+ } +
); } diff --git a/src/app/components/ModificationsMenu.jsx b/src/app/components/ModificationsMenu.jsx index 6bf82707..9607d475 100644 --- a/src/app/components/ModificationsMenu.jsx +++ b/src/app/components/ModificationsMenu.jsx @@ -15,6 +15,10 @@ import { specialToolTip } from '../utils/BlueprintFunctions'; +const MODIFICATIONS_COMPARATOR = (mod1, mod2) => { + return mod1.props.name.localeCompare(mod2.props.name); +}; + /** * Modifications menu */ @@ -124,7 +128,7 @@ export default class ModificationsMenu extends TranslatedComponent { // Initial modification menu event.preventDefault(); this.modItems[this.lastModId].focus(); - return; + return; } else if (event.currentTarget.className.indexOf('button-inline-menu') >= 0 && event.currentTarget.previousElementSibling == null && this.lastNeId != null && this.modItems[this.lastNeId] != null) { // shift-tab on first element in modifications menu. set focus to last number editor field if open event.preventDefault(); @@ -205,15 +209,26 @@ export default class ModificationsMenu extends TranslatedComponent { */ _renderModifications(props) { const { m, onChange, ship } = props; + const modifiableModifications = []; const modifications = []; for (const modName of Modifications.modules[m.grp].modifications) { if (!Modifications.modifications[modName].hidden) { const key = modName + (m.getModValue(modName) / 100 || 0); + const editable = modName !== 'fallofffromrange' && + m.blueprint.grades[m.blueprint.grade].features[modName]; this.lastNeId = modName; - modifications.push(); + (editable ? modifiableModifications : modifications).push( + + ); } } - return modifications; + + modifiableModifications.sort(MODIFICATIONS_COMPARATOR); + modifications.sort(MODIFICATIONS_COMPARATOR); + return modifiableModifications.concat(modifications); } /** diff --git a/src/app/i18n/Language.jsx b/src/app/i18n/Language.jsx index 6946ae0f..3a6cc61b 100644 --- a/src/app/i18n/Language.jsx +++ b/src/app/i18n/Language.jsx @@ -60,12 +60,14 @@ export function getLanguage(langCode) { }, translate, units: { + ang: '°', // Angle CR: {translate('CR')}, // Credits kg: {translate('kg')}, // Kilograms kgs: {translate('kg/s')}, // Kilograms per second km: {translate('km')}, // Kilometers Ls: {translate('Ls')}, // Light Seconds LY: {translate('LY')}, // Light Years + m: {translate('m')}, // Meters MJ: {translate('MJ')}, // Mega Joules 'm/s': {translate('m/s')}, // Meters per second '°/s': {translate('°/s')}, // Degrees per second diff --git a/src/app/i18n/en.json b/src/app/i18n/en.json index f35f444c..d142c819 100644 --- a/src/app/i18n/en.json +++ b/src/app/i18n/en.json @@ -178,6 +178,7 @@ "dpssdps": "Damage per second (sustained damage per second)", "eps": "Energy per second", "epsseps": "Energy per second (sustained energy per second)", + "fallofffromrange": "Falloff", "hps": "Heat per second", "hpsshps": "Heat per second (sustained heat per second)", "damage by": "Damage by", diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index afed8fae..1019e4b5 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -1,5 +1,7 @@ import * as ModuleUtils from './ModuleUtils'; import { Modifications } from 'coriolis-data/dist'; +import React from 'react'; +import { STATS_FORMATING, SI_PREFIXES } from './StatsFormating'; /** * Module - active module in a ship's buildout @@ -41,7 +43,14 @@ export default class Module { */ getModValue(name, raw) { let result = this.mods && this.mods[name] ? this.mods[name] : null; - if ((!raw) && this.blueprint && this.blueprint.special) { + + // Calculate the percentage change for a synthetic value + if (STATS_FORMATING[name] && STATS_FORMATING[name].synthetic) { + const statGetter = this[STATS_FORMATING[name].synthetic]; + let unmodifiedStat = statGetter.call(this, false); + let modifiedStat = statGetter.call(this, true); + result = (modifiedStat / unmodifiedStat - 1) * 10000; + } else if ((!raw) && this.blueprint && this.blueprint.special) { // This module has a special effect, see if we need to alter our returned value const modifierActions = Modifications.modifierActions[this.blueprint.special.edname]; if (modifierActions && modifierActions[name]) { @@ -72,6 +81,7 @@ export default class Module { } } } + // Sanitise the resultant value to 4dp equivalent return isNaN(result) ? result : Math.round(result); } @@ -119,24 +129,29 @@ export default class Module { } } + /** + * Helper to obtain a module's value. + * @param {String} name The name of the modifier to obtain + * @param {Number} modified Whether to return the raw or modified value + * @return {Number} The value queried + */ + _getValue(name, modified) { + if (modified) { + return this._getModifiedValue(name); + } else { + return this[name]; + } + } + /** * Helper to obtain a modified value using standard multipliers * @param {String} name the name of the modifier to obtain - * @return {Number} the mass of this module + * @return {Number} the value queried */ _getModifiedValue(name) { const modification = Modifications.modifications[name]; let result = this[name]; - if (!result) { - if (modification && modification.method === 'additive') { - // Additive modifications start at 0 rather than NULL - result = 0; - } else { - result = null; - } - } - if (result != null) { if (modification) { // We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise // we divide by 100. Both ways we end up with a value with two decimal places @@ -149,6 +164,13 @@ export default class Module { modValue = this.getModValue(name); } if (modValue) { + if (!result && modification.method === 'additive') { + // If the modification is additive and no value is given by default we + // start at zero + result = 0; + } + + if (result !== undefined) { if (modification.method === 'additive') { // Resistance modding for hull reinforcement packages has additional // diminishing returns implemented. The mod value gets lowered by @@ -165,15 +187,11 @@ export default class Module { } else { result = result * (1 + modValue); } - } + } else if (name === 'burst' || name === 'burstrof') { + // Burst and burst rate of fire are special, as it can not exist but + // have a modification + result = modValue / 100; } - } else { - if (name === 'burst') { - // Burst is special, as if it can not exist but have a modification - result = this.getModValue(name) / 100; - } else if (name === 'burstrof') { - // Burst rate of fire is special, as if it can not exist but have a modification - result = this.getModValue(name) / 100; } } @@ -181,249 +199,349 @@ export default class Module { } /** - * Get the power generation of this module, taking in to account modifications + * Creates a react element that pretty-prints the queried module value + * @param {String} name The name of the value + * @param {object} language Language object holding formats and util functions + * @param {String} [unit] If unit is given not the stat's default formating + * unit will be applied but the given one taking into + * account SI-prefixes such as kilo, milli, etc. + * @param {Number} [val] If val is given, not the modules value but given + * one will be formated + * @returns {React.Component} The formated value as component + */ + formatModifiedValue(name, language, unit, val) { + const formatingOptions = STATS_FORMATING[name]; + if (val === undefined) { + if (formatingOptions && formatingOptions.synthetic) { + val = (this[formatingOptions.synthetic]).call(this, true); + } else { + val = this._getModifiedValue(name); + } + } + + val = val || 0; + + if (!formatingOptions) { + return ( + + {val} + + ); + } + + let { format } = formatingOptions; + unit = unit || formatingOptions.unit; + let storedUnit = formatingOptions.storedUnit || formatingOptions.unit; + let factor = 1; + if (storedUnit && storedUnit !== unit) { + // Find out si prefix of storedUnit and unit as si prefixes can only take + // on charactere it suffices to compare the first character of each string + let prefixUnit = unit[0]; + let prefixStored = unit[0]; + if (unit.length > storedUnit.length) { + factor /= SI_PREFIXES[prefixUnit]; + } else if (storedUnit.length > unit.length) { + factor *= SI_PREFIXES[prefixStored]; + } else if (prefixUnit !== prefixStored) { + factor *= SI_PREFIXES[prefixStored]; + factor /= SI_PREFIXES[prefixUnit]; + } + } + + if (format && language.formats[format]) { + val = (language.formats[format])(val * factor); + } + + return ( + + {val} + {formatingOptions.unit && language.units[formatingOptions.unit]} + + ); + } + + /** + * Get the power generation of this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the power generation of this module */ - getPowerGeneration() { - return this._getModifiedValue('pgen'); + getPowerGeneration(modified = true) { + return this._getValue('pgen', modified); } /** - * Get the power usage of this module, taking in to account modifications + * Get the power usage of this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the power usage of this module */ - getPowerUsage() { - return this._getModifiedValue('power'); + getPowerUsage(modified = true) { + return this._getValue('power', modified); } /** - * Get the integrity of this module, taking in to account modifications + * Get the integrity of this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the integrity of this module */ - getIntegrity() { - return this._getModifiedValue('integrity'); + getIntegrity(modified = true) { + return this._getValue('integrity', modified); } /** - * Get the mass of this module, taking in to account modifications + * Get the mass of this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the mass of this module */ - getMass() { - return this._getModifiedValue('mass'); + getMass(modified = true) { + return this._getValue('mass', modified); } /** - * Get the thermal efficiency of this module, taking in to account modifications + * Get the thermal efficiency of this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the thermal efficiency of this module */ - getThermalEfficiency() { - return this._getModifiedValue('eff'); + getThermalEfficiency(modified = true) { + return this._getValue('eff', modified); } /** - * Get the maximum fuel per jump for this module, taking in to account modifications + * Get the maximum fuel per jump for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the maximum fuel per jump of this module */ - getMaxFuelPerJump() { - return this._getModifiedValue('maxfuel'); + getMaxFuelPerJump(modified = true) { + return this._getValue('maxfuel', modified); } /** - * Get the systems capacity for this module, taking in to account modifications + * Get the systems capacity for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the systems capacity of this module */ - getSystemsCapacity() { - return this._getModifiedValue('syscap'); + getSystemsCapacity(modified = true) { + return this._getValue('syscap', modified); } /** - * Get the engines capacity for this module, taking in to account modifications + * Get the engines capacity for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the engines capacity of this module */ - getEnginesCapacity() { - return this._getModifiedValue('engcap'); + getEnginesCapacity(modified = true) { + return this._getValue('engcap', modified); } /** - * Get the weapons capacity for this module, taking in to account modifications + * Get the weapons capacity for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the weapons capacity of this module */ - getWeaponsCapacity() { - return this._getModifiedValue('wepcap'); + getWeaponsCapacity(modified = true) { + return this._getValue('wepcap', modified); } /** - * Get the systems recharge rate for this module, taking in to account modifications + * Get the systems recharge rate for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the systems recharge rate of this module */ - getSystemsRechargeRate() { - return this._getModifiedValue('sysrate'); + getSystemsRechargeRate(modified = true) { + return this._getValue('sysrate', modified); } /** - * Get the engines recharge rate for this module, taking in to account modifications + * Get the engines recharge rate for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the engines recharge rate of this module */ - getEnginesRechargeRate() { - return this._getModifiedValue('engrate'); + getEnginesRechargeRate(modified = true) { + return this._getValue('engrate', modified); } /** - * Get the weapons recharge rate for this module, taking in to account modifications + * Get the weapons recharge rate for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the weapons recharge rate of this module */ - getWeaponsRechargeRate() { - return this._getModifiedValue('weprate'); + getWeaponsRechargeRate(modified = true) { + return this._getValue('weprate', modified); } /** - * Get the kinetic resistance for this module, taking in to account modifications + * Get the kinetic resistance for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the kinetic resistance of this module */ - getKineticResistance() { - return this._getModifiedValue('kinres'); + getKineticResistance(modified = true) { + return this._getValue('kinres', modified); } /** - * Get the thermal resistance for this module, taking in to account modifications + * Get the thermal resistance for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the thermal resistance of this module */ - getThermalResistance() { - return this._getModifiedValue('thermres'); + getThermalResistance(modified = true) { + return this._getValue('thermres', modified); } /** - * Get the explosive resistance for this module, taking in to account modifications + * Get the explosive resistance for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the explosive resistance of this module */ - getExplosiveResistance() { - return this._getModifiedValue('explres'); - } - - getCausticResistance() { - return this._getModifiedValue('causres'); + getExplosiveResistance(modified = true) { + return this._getValue('explres', modified); } /** - * Get the regeneration rate for this module, taking in to account modifications + * Get the caustic resistance for this module + * @param {Boolean} [modified=true] Whether to take modifications into account + * @return {Number} the caustic resistance of this module + */ + getCausticResistance(modified = true) { + return this._getValue('causres', modified); + } + + /** + * Get the regeneration rate for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the regeneration rate of this module */ - getRegenerationRate() { - return this._getModifiedValue('regen'); + getRegenerationRate(modified = true) { + return this._getValue('regen', modified); } /** - * Get the broken regeneration rate for this module, taking in to account modifications + * Get the broken regeneration rate for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the broken regeneration rate of this module */ - getBrokenRegenerationRate() { - return this._getModifiedValue('brokenregen'); + getBrokenRegenerationRate(modified = true) { + return this._getValue('brokenregen', modified); } /** - * Get the range for this module, taking in to account modifications + * Get the range for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the range rate of this module */ - getRange() { - return this._getModifiedValue('range'); + getRange(modified = true) { + return this._getValue('range', modified); } /** - * Get the falloff for this module, taking in to account modifications + * Get the falloff for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the falloff of this module */ - getFalloff() { - if (this.getModValue('fallofffromrange')) { - // Falloff from range means what it says, so use range instead of falloff + getFalloff(modified = true) { + if (!modified) { + const range = this.getRange(false); + const falloff = this._getValue('falloff', false); + return (falloff > range ? range : falloff); + } + + // Falloff from range is mapped to range + if (this.mods && this.mods['fallofffromrange']) { return this.getRange(); + // Need to find out if we have a focused modification, in which case our + // falloff is scaled to range + } else if (this.blueprint && this.blueprint.name === 'Focused') { + const rangeMod = this.getModValue('range') / 10000; + return this.falloff * (1 + rangeMod); + // Standard falloff calculation } else { - // Need to find out if we have a focused modification, in which case our falloff is scaled to range - if (this.blueprint && this.blueprint.name === 'Focused') { - const rangeMod = this.getModValue('range') / 10000; - return this.falloff * (1 + rangeMod); - } else { - // Standard falloff calculation - const range = this.getRange(); - const falloff = this._getModifiedValue('falloff'); - return (falloff > range ? range : falloff); - } + const range = this.getRange(); + const falloff = this._getModifiedValue('falloff'); + return (falloff > range ? range : falloff); } } /** - * Get the range (in terms of seconds, for FSDI) for this module, taking in to account modifications + * Get the range (in terms of seconds, for FSDI) for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the range of this module */ - getRangeT() { - return this._getModifiedValue('ranget'); + getRangeT(modified = true) { + return this._getValue('ranget', modified); } /** - * Get the scan time for this module, taking in to account modifications + * Get the scan time for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the scan time of this module */ - getScanTime() { - return this._getModifiedValue('scantime'); + getScanTime(modified = true) { + return this._getValue('scantime', modified); } /** - * Get the capture arc for this module, taking in to account modifications + * Get the capture arc for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the capture arc of this module */ - getCaptureArc() { - return this._getModifiedValue('arc'); + getCaptureArc(modified = true) { + return this._getValue('arc', modified); } /** - * Get the hull reinforcement for this module, taking in to account modifications + * Get the hull reinforcement for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the hull reinforcement of this module */ - getHullReinforcement() { - return this._getModifiedValue('hullreinforcement'); + getHullReinforcement(modified = true) { + return this._getValue('hullreinforcement', modified); } /** - * Get the protection for this module, taking in to account modifications + * Get the protection for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the protection of this module */ - getProtection() { - return this._getModifiedValue('protection'); + getProtection(modified = true) { + return this._getValue('protection', modified); } /** - * Get the delay for this module, taking in to account modifications + * Get the delay for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the delay of this module */ - getDelay() { - return this._getModifiedValue('delay'); + getDelay(modified = true) { + return this._getValue('delay', modified); } /** - * Get the duration for this module, taking in to account modifications + * Get the duration for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the duration of this module */ - getDuration() { - return this._getModifiedValue('duration'); + getDuration(modified = true) { + return this._getValue('duration', modified); } /** - * Get the shield boost for this module, taking in to account modifications + * Get the shield boost for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the shield boost of this module */ - getShieldBoost() { - return this._getModifiedValue('shieldboost'); + getShieldBoost(modified = true) { + return this._getValue('shieldboost', modified); } /** - * Get the minimum mass for this module, taking in to account modifications + * Get the minimum mass for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the minimum mass of this module */ - getMinMass() { + getMinMass(modified = true) { // Modifier is optmass let result = 0; if (this['minmass']) { result = this['minmass']; - if (result) { + if (result && modified) { let mult = this.getModValue('optmass') / 10000; if (mult) { result = result * (1 + mult); } } @@ -432,24 +550,26 @@ export default class Module { } /** - * Get the optimum mass for this module, taking in to account modifications + * Get the optimum mass for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the optimum mass of this module */ - getOptMass() { - return this._getModifiedValue('optmass'); + getOptMass(modified = true) { + return this._getValue('optmass', modified); } /** - * Get the maximum mass for this module, taking in to account modifications + * Get the maximum mass for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the maximum mass of this module */ - getMaxMass() { + getMaxMass(modified = true) { // Modifier is optmass let result = 0; if (this['maxmass']) { result = this['maxmass']; // max mass is only modified for non-shield boosters - if (result && this.grp !== 'sg') { + if (result && modified && this.grp !== 'sg') { let mult = this.getModValue('optmass') / 10000; if (mult) { result = result * (1 + mult); } } @@ -458,11 +578,12 @@ export default class Module { } /** - * Get the minimum multiplier for this module, taking in to account modifications + * Get the minimum multiplier for this module * @param {string} type the type for which we are obtaining the multiplier. Can be 'speed', 'rotation', 'acceleration', or null + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the minimum multiplier of this module */ - getMinMul(type = null) { + getMinMul(type = null, modified = true) { // Modifier is optmul let result = 0; if (this['minmul' + type]) { @@ -470,7 +591,7 @@ export default class Module { } else if (this['minmul']) { result = this['minmul']; } - if (result) { + if (result && modified) { let mult = this.getModValue('optmul') / 10000; if (mult) { result = result * (1 + mult); } } @@ -478,11 +599,12 @@ export default class Module { } /** - * Get the optimum multiplier for this module, taking in to account modifications + * Get the optimum multiplier for this module * @param {string} type the type for which we are obtaining the multiplier. Can be 'speed', 'rotation', 'acceleration', or null + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the optimum multiplier of this module */ - getOptMul(type = null) { + getOptMul(type = null, modified = true) { // Modifier is optmul let result = 0; if (this['optmul' + type]) { @@ -490,7 +612,7 @@ export default class Module { } else if (this['optmul']) { result = this['optmul']; } - if (result) { + if (result && modified) { let mult = this.getModValue('optmul') / 10000; if (mult) { result = result * (1 + mult); } } @@ -498,11 +620,12 @@ export default class Module { } /** - * Get the maximum multiplier for this module, taking in to account modifications + * Get the maximum multiplier for this module * @param {string} type the type for which we are obtaining the multiplier. Can be 'speed', 'rotation', 'acceleration', or null + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the maximum multiplier of this module */ - getMaxMul(type = null) { + getMaxMul(type = null, modified = true) { // Modifier is optmul let result = 0; if (this['maxmul' + type]) { @@ -510,7 +633,7 @@ export default class Module { } else if (this['maxmul']) { result = this['maxmul']; } - if (result) { + if (result && modified) { let mult = this.getModValue('optmul') / 10000; if (mult) { result = result * (1 + mult); } } @@ -518,266 +641,302 @@ export default class Module { } /** - * Get the damage for this module, taking in to account modifications + * Get the damage for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the damage of this module */ - getDamage() { - return this._getModifiedValue('damage'); + getDamage(modified = true) { + return this._getValue('damage', modified); } /** - * Get the distributor draw for this module, taking in to account modifications + * Get the distributor draw for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the distributor draw of this module */ - getDistDraw() { - return this._getModifiedValue('distdraw'); + getDistDraw(modified = true) { + return this._getValue('distdraw', modified); } /** - * Get the thermal load for this module, taking in to account modifications + * Get the thermal load for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the thermal load of this module */ - getThermalLoad() { - return this._getModifiedValue('thermload'); + getThermalLoad(modified = true) { + return this._getValue('thermload', modified); } /** - * Get the rounds per shot for this module, taking in to account modifications + * Get the rounds per shot for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the rounds per shot of this module */ - getRoundsPerShot() { - return this._getModifiedValue('roundspershot'); + getRoundsPerShot(modified = true) { + return this._getValue('roundspershot', modified); } /** - * Get the DPS for this module, taking in to account modifications + * Get the DPS for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the DPS of this module */ - getDps() { + getDps(modified = true) { // DPS is a synthetic value - let damage = this.getDamage(); + let damage = this.getDamage(modified); let rpshot = this.roundspershot || 1; - let rof = this.getRoF() || 1; + let rof = this.getRoF(modified) || 1; return damage * rpshot * rof; } /** - * Get the SDPS for this module, taking into account modifications and special - * effects. + * Get the DPE for this module + * @param {Boolean} [modified=true] Whether to take modifications into account + * @return {Number} the DPE of this module + */ + getDpe(modified = true) { + return this.getDps(modified) / this.getEps(modified); + } + + /** + * Get the SDPS for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} The SDPS of this module */ - getSDps() { - let dps = this.getDps(); - if (this.getClip()) { - let clipSize = this.getClip(); + getSDps(modified = true) { + let dps = this.getDps(modified); + if (this.getClip(modified)) { + let clipSize = this.getClip(modified); // If auto-loader is applied, effective clip size will be nearly doubled // as you get one reload for every two shots fired. - if (this.blueprint && this.blueprint.special && this.blueprint.special.edname === 'special_auto_loader') { + if (this.blueprint && this.blueprint.special && this.blueprint.special.edname === 'special_auto_loader' && modified) { clipSize += clipSize - 1; } - let timeToDeplete = clipSize / this.getRoF(); - return dps * timeToDeplete / (timeToDeplete + this.getReload()); + let timeToDeplete = clipSize / this.getRoF(modified); + return dps * timeToDeplete / (timeToDeplete + this.getReload(modified)); } else { return dps; } } /** - * Get the EPS for this module, taking in to account modifications + * Get the EPS for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the EPS of this module */ - getEps() { + getEps(modified = true) { // EPS is a synthetic value - let distdraw = this.getDistDraw(); + let distdraw = this.getDistDraw(modified); // We don't use rpshot here as dist draw is per combined shot - let rof = this.getRoF() || 1; + let rof = this.getRoF(modified) || 1; return distdraw * rof; } /** - * Get the HPS for this module, taking in to account modifications + * Get the HPS for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the HPS of this module */ - getHps() { + getHps(modified = true) { // HPS is a synthetic value - let heat = this.getThermalLoad(); + let heat = this.getThermalLoad(modified); // We don't use rpshot here as dist draw is per combined shot - let rof = this.getRoF() || 1; + let rof = this.getRoF(modified) || 1; return heat * rof; } /** - * Get the clip size for this module, taking in to account modifications + * Get the clip size for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the clip size of this module */ - getClip() { + getClip(modified = true) { // Clip size is always rounded up - let result = this._getModifiedValue('clip'); + let result = this._getValue('clip', modified); if (result) { result = Math.ceil(result); } return result; } /** - * Get the ammo size for this module, taking in to account modifications + * Get the ammo size for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the ammo size of this module */ - getAmmo() { - return this._getModifiedValue('ammo'); + getAmmo(modified = true) { + return this._getValue('ammo', modified); } /** - * Get the reload time for this module, taking in to account modifications + * Get the reload time for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the reload time of this module */ - getReload() { - return this._getModifiedValue('reload'); + getReload(modified = true) { + return this._getValue('reload', modified); } /** - * Get the burst size for this module, taking in to account modifications + * Get the burst size for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the burst size of this module */ - getBurst() { - return this._getModifiedValue('burst'); + getBurst(modified = true) { + return this._getValue('burst', modified); } /** - * Get the burst rate of fire for this module, taking in to account modifications + * Get the burst rate of fire for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the burst rate of fire of this module */ - getBurstRoF() { - return this._getModifiedValue('burstrof'); + getBurstRoF(modified = true) { + return this._getValue('burstrof', modified); } /** - * Get the rate of fire for this module, taking in to account modifications. + * Get the rate of fire for this module. * The rate of fire is a combination value, and needs to take in to account * bursts of fire. * Firing goes [burst 1] [burst interval] [burst 2] [burst interval] ... [burst n] [interval] * where 'n' is 'burst', 'burst interval' is '1/burstrof' and 'interval' is '1/rof' + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the rate of fire for this module */ - getRoF() { - const burst = this.getBurst() || 1; - const burstRoF = this.getBurstRoF() || 1; - const intRoF = this._getModifiedValue('rof'); + getRoF(modified = true) { + const burst = this.getBurst(modified) || 1; + const burstRoF = this.getBurstRoF(modified) || 1; + const intRoF = this._getValue('rof', modified); return burst / (((burst - 1) / burstRoF) + 1 / intRoF); } /** - * Get the facing limit for this module, taking in to account modifications + * Get the facing limit for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the facing limit for this module */ - getFacingLimit() { - return this._getModifiedValue('facinglimit'); + getFacingLimit(modified = true) { + return this._getValue('facinglimit', modified); } /** - * Get the hull boost for this module, taking in to account modifications + * Get the hull boost for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the hull boost for this module */ - getHullBoost() { - return this._getModifiedValue('hullboost'); + getHullBoost(modified = true) { + return this._getValue('hullboost', modified); } /** - * Get the shield reinforcement for this module, taking in to account modifications + * Get the shield reinforcement for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the shield reinforcement for this module */ - getShieldReinforcement() { - return this._getModifiedValue('shieldreinforcement'); + getShieldReinforcement(modified = true) { + return this._getValue('shieldreinforcement', modified); } /** - * Get the shield addition for this module, taking in to account modifications + * Get the shield addition for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the shield addition for this module */ - getShieldAddition() { - return this._getModifiedValue('shieldaddition'); + getShieldAddition(modified = true) { + return this._getValue('shieldaddition', modified); } /** - * Get the jump range boost for this module, taking in to account modifications + * Get the jump range boost for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the jump range boost for this module */ - getJumpBoost() { - return this._getModifiedValue('jumpboost'); + getJumpBoost(modified = true) { + return this._getValue('jumpboost', modified); } /** - * Get the piercing for this module, taking in to account modifications + * Get the piercing for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the piercing for this module */ - getPiercing() { - return this._getModifiedValue('piercing'); + getPiercing(modified = true) { + return this._getValue('piercing', modified); } /** - * Get the bays for this module, taking in to account modifications + * Get the bays for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the bays for this module */ - getBays() { - return this._getModifiedValue('bays'); + getBays(modified) { + return this._getValue('bays', modified); } /** - * Get the rebuilds per bay for this module, taking in to account modifications + * Get the rebuilds per bay for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the rebuilds per bay for this module */ - getRebuildsPerBay() { - return this._getModifiedValue('rebuildsperbay'); + getRebuildsPerBay(modified = true) { + return this._getValue('rebuildsperbay', modified); } /** - * Get the jitter for this module, taking in to account modifications + * Get the jitter for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {Number} the jitter for this module */ - getJitter() { - return this._getModifiedValue('jitter', true); + getJitter(modified = true) { + return this._getValue('jitter', modified); } /** - * Get the damage distribution for this module, taking in to account modifications + * Get the damage distribution for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {string} the damage distribution for this module */ - getDamageDist() { - return this.getModValue('damagedist') || this.damagedist; + getDamageDist(modified = true) { + return (modified && this.getModValue('damagedist')) || this.damagedist; } /** - * Get the shot speed for this module, taking in to account modifications + * Get the shot speed for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {string} the shot speed for this module */ - getShotSpeed() { - return this._getModifiedValue('shotspeed'); + getShotSpeed(modified = true) { + return this._getValue('shotspeed', modified); } /** - * Get the spinup for this module, taking in to account modifications + * Get the spinup for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {string} the spinup for this module */ - getSpinup() { - return this._getModifiedValue('spinup'); + getSpinup(modified = true) { + return this._getValue('spinup', modified); } /** - * Get the time for this module, taking in to account modifications + * Get the time for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {string} the time for this module */ - getTime() { - return this._getModifiedValue('time'); + getTime(modified = true) { + return this._getValue('time', modified); } /** - * Get the hack time for this module, taking in to account modifications + * Get the hack time for this module + * @param {Boolean} [modified=true] Whether to take modifications into account * @return {string} the time for this module */ - getHackTime() { - return this._getModifiedValue('hacktime'); + getHackTime(modified = true) { + return this._getValue('hacktime', modified); } } diff --git a/src/app/shipyard/StatsFormating.js b/src/app/shipyard/StatsFormating.js new file mode 100644 index 00000000..1beb772a --- /dev/null +++ b/src/app/shipyard/StatsFormating.js @@ -0,0 +1,82 @@ +export const SI_PREFIXES = { + 'Y': 1e+24, // Yotta + 'Z': 1e+21, // Zetta + 'E': 1e+18, // Peta + 'P': 1e+15, // Peta + 'T': 1e+12, // Tera + 'G': 1e+9, // Giga + 'M': 1e+6, // Mega + 'k': 1e+3, // Kilo + 'h': 1e+2, // Hekto + 'da': 1e+1, // Deka + '': 1, + 'd': 1e-1, // Dezi + 'c': 1e-2, // Zenti + 'm': 1e-3, // Milli + 'μ': 1e-6, // mikro not supported due to charset + 'n': 10e-9, // Nano + 'p': 1e-12, // Nano + 'f': 1e-15, // Femto + 'a': 1e-18, // Atto + 'z': 1e-21, // Zepto + 'y': 1e-24 // Yokto +}; + +export const STATS_FORMATING = { + 'ammo': { 'format': 'int', }, + 'boot': { 'format': 'int', 'unit': 'secs' }, + 'brokenregen': { 'format': 'round1', 'unit': 'ps' }, + 'burst': { 'format': 'int' }, + 'burstrof': { 'format': 'round1', 'unit': 'ps' }, + 'causres': { 'format': 'pct' }, + 'clip': { 'format': 'int' }, + 'damage': { 'format': 'round' }, + 'dps': { 'format': 'round', 'units': 'ps', 'synthetic': 'getDps' }, + 'dpe': { 'format': 'round', 'units': 'ps', 'synthetic': 'getDpe' }, + 'distdraw': { 'format': 'round', 'unit': 'MW' }, + 'duration': { 'format': 'round1', 'unit': 's' }, + 'eff': { 'format': 'round2' }, + 'engcap': { 'format': 'round1', 'unit': 'MJ' }, + 'engrate': { 'format': 'round1', 'unit': 'MW' }, + 'eps': { 'format': 'round', 'units': 'ps', 'synthetic': 'getEps' }, + 'explres': { 'format': 'pct' }, + 'facinglimit': { 'format': 'round1', 'unit': 'ang' }, + 'falloff': { 'format': 'round', 'unit': 'km', 'storedUnit': 'm' }, + 'fallofffromrange': { 'format': 'round', 'unit': 'km', 'storedUnit': 'm', 'synthetic': 'getFalloff' }, + 'hps': { 'format': 'round', 'units': 'ps', 'synthetic': 'getHps' }, + 'hullboost': { 'format': 'pct1' }, + 'hullreinforcement': { 'format': 'int' }, + 'integrity': { 'format': 'round1' }, + 'jitter': { 'format': 'round', 'unit': 'ang' }, + 'kinres': { 'format': 'pct' }, + 'mass': { 'format': 'round1', 'unit': 'T' }, + 'maxfuel': { 'format': 'round1', 'unit': 'T' }, + 'optmass': { 'format': 'int', 'unit': 'T' }, + 'optmul': { 'format': 'pct' }, + 'pgen': { 'format': 'round1', 'unit': 'MW' }, + 'piercing': { 'format': 'int' }, + 'power': { 'format': 'round', 'unit': 'MW' }, + 'protection': { 'format': 'pct' }, + 'range': { 'format': 'f2', 'unit': 'km', 'storedUnit': 'm' }, + 'ranget': { 'format': 'f1', 'unit': 's' }, + 'regen': { 'format': 'round1', 'unit': 'ps' }, + 'reload': { 'format': 'int', 'unit': 's' }, + 'rof': { 'format': 'round1', 'unit': 'ps' }, + 'angle': { 'format': 'round1', 'unit': 'ang' }, + 'scanrate': { 'format': 'int' }, + 'scantime': { 'format': 'round1', 'unit': 's' }, + 'sdps': { 'format': 'round1', 'units': 'ps', 'synthetic': 'getSDps' }, + 'shield': { 'format': 'int', 'unit': 'MJ' }, + 'shieldaddition': { 'format': 'round1', 'unit': 'MJ' }, + 'shieldboost': { 'format': 'pct1' }, + 'shieldreinforcement': { 'format': 'round1', 'unit': 'MJ' }, + 'shotspeed': { 'format': 'int', 'unit': 'm/s' }, + 'spinup': { 'format': 'round1', 'unit': 's' }, + 'syscap': { 'format': 'round1', 'unit': 'MJ' }, + 'sysrate': { 'format': 'round1', 'unit': 'MW' }, + 'thermload': { 'format': 'round1' }, + 'thermres': { 'format': 'pct' }, + 'wepcap': { 'format': 'round1', 'unit': 'MJ' }, + 'weprate': { 'format': 'round1', 'unit': 'MW' }, + 'jumpboost': { 'format': 'round1', 'unit': 'LY' } +}; diff --git a/src/less/slot.less b/src/less/slot.less index 095de72a..9b05bce3 100755 --- a/src/less/slot.less +++ b/src/less/slot.less @@ -45,6 +45,11 @@ border-color:#fff; } + input:disabled { + border-color: #888; + color: #888; + } + .l { text-transform: capitalize; margin-right: 0.8em;