diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index e482b09d..c68f7609 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 StatsFormating 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 (StatsFormating[name] && StatsFormating[name].synthetic) { + const statGetter = this[StatsFormating[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); } @@ -136,7 +146,7 @@ export default class Module { /** * 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]; @@ -187,6 +197,44 @@ export default class Module { return result; } + /** + * 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 {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, val) { + const formatingOptions = StatsFormating[name]; + if (val === undefined) { + if (formatingOptions && formatingOptions.synthetic) { + val = (this[formatingOptions.synthetic]).call(this, true); + } else { + val = this._getModifiedValue(name); + } + } + + if (!formatingOptions) { + return ( + + {val} + + ); + } + + if (formatingOptions.format && language.formats[formatingOptions.format]) { + val = (language.formats[formatingOptions.format])(val); + } + + 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 @@ -373,17 +421,15 @@ export default class Module { // Falloff from range is mapped to range if (this.mods['fallofffromrange']) { return this.getRange(); + // If range is modified but not falloff, increase the falloff to keep ratio + } else if (this.getModValue('range')) { + 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); } } @@ -618,6 +664,14 @@ export default class Module { } /** + * 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 diff --git a/src/app/shipyard/StatsFormating.js b/src/app/shipyard/StatsFormating.js new file mode 100644 index 00000000..699e379f --- /dev/null +++ b/src/app/shipyard/StatsFormating.js @@ -0,0 +1,58 @@ +export default { + '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': 'round1', 'unit': 'm' }, + 'fallofffromrange': { 'format': 'round1', 'unit': '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': 'round1', 'unit': 'm' }, + 'ranget': { 'format': 'round1', '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' } +};