From e448b3cb0a833a5bdadcca2f3ba1ac4637e41ff1 Mon Sep 17 00:00:00 2001 From: Cmdr McDonald Date: Thu, 26 Jan 2017 16:06:29 +0000 Subject: [PATCH] Add specials --- ChangeLog.md | 1 + __tests__/test-import.js | 2 +- src/app/components/InternalSlot.jsx | 6 +- src/app/components/Modification.jsx | 2 +- src/app/components/ModificationsMenu.jsx | 105 ++++++++++++---- src/app/i18n/en.js | 2 + src/app/shipyard/Module.js | 147 +++++++++++++++++------ src/app/shipyard/Ship.js | 41 ++++--- src/app/utils/CompanionApiUtils.js | 8 +- 9 files changed, 220 insertions(+), 94 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 4f79de49..62ea91bf 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,6 @@ #2.2.12 * Tidy up old references to coriolis.io + * Add ability to add and remove special effects to weapon modifications #2.2.11 * Add help system and initial help file diff --git a/__tests__/test-import.js b/__tests__/test-import.js index 42d6fe06..9a069359 100644 --- a/__tests__/test-import.js +++ b/__tests__/test-import.js @@ -238,7 +238,7 @@ describe('Import Modal', function() { expect(modal.state.singleBuild).toBe(true); clickProceed(); expect(MockRouter.go.mock.calls.length).toBe(1); - expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=A2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifr--v66g2f.AwRj4zNaqA%3D%3D.CwRgDBldUExuBiIlUA%3D%3D.H4sIAAAAAAAAA02Svy9DURTHT1vvtfoat32eekVV9fm1kBgwSIw0YWYgBqmpMZkMBomFVfwFEoZKhBjE1qWTgegiDX%2BCQdKI1j2%2BR%2FJ4yzfnvu%2FnfO%2B979yQXiCi7xAkbRpEqsLMsRKWHNZpsSKQnppJVLAdIvc6DGiwxexMaWb7GDZHdJ%2BQaCf71Ia%2F88XsOp1EThk9bOh5P2kkahGN3qPM1wANbyOk87zNHH%2FBUs0gnWN61T9TOwfJ7EWJjMcms1lEo30Gx11BD8f1mh%2FcTkCMMvY0HZcoe4Wk5By%2BFcrrRL0N0OOlrd0Ntv57jGoc%2BH4%2F8EqHj3%2FCUXc4FicC5NFvsJBVIWeFvESlpuXSuCS5RRyLlV70z%2B4uQaw6ypSIJ6KOJDgZgFpQ60YgEU9EPQmUCkAfAj0IJOKJqC4wuYMY9rQD5CuubT0LSag8qdShxHUHoElcyWrAT4l4IsoCw65e%2BRv5BqKtC0mSJu8LH8OFT%2Bb%2BE8SZb0CcEn4AZ3TRDx5q4l1EJ%2BCP1bEM1WSaAwH%2FFkOLPoofwTo0LY8nr7O%2B37cp4yWIu4zHlHiXGfMPmat5gqMCAAA%3D&bn=Imported%20Federal%20Corvette'); + expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=A2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifr--v66g2f.AwRj4zNaqA%3D%3D.CwRgDBldUExuBiIlUA%3D%3D.H4sIAAAAAAAAA02SPy9DURjG3%2F65vW1v47TXVbeqqF7EQtIIBomRJswsYmISH8BgkFhqFZ9AwlALMYitkXQyEF2k4SMYJNK0dV7PK7nc5ck55%2Fm9z%2FnznpBeJqLvECQbM4hUjZnjO5hyWGfFikAGGjGiku0QuddhQCNdZmdWM9snsDmih4REOdlnNvz9DrPrJIicPdSwoZf8pAnTIpq8x7DYADS%2Bi5DERY85%2BYqpmkc6x%2FWGf6beKCR3YBIZFZCxCgrtczjuOmo4qTf94F4KYuxhz5jjEhXmUJNexFrpIUo02ALN1j9u1JMgD%2FMga1GfbMNRd9iHUwGy%2BpspZF3IBSGvMFJluS%2FuR24FJ2KlV%2Fxju6sQq4lhRsQTUVUJTgegLtS6EUjEE1HPAmUC0KdAjwKJeCKqD8zoURx72gHyDW9nvQhJGHkyUscS1x%2BAZnAlqwU%2FI%2BKJKEvextXrf93eQrR1KUlS5HWwGC61mfOn0oN3IM4OHoBzuuIHj33hS5jT8KeamIYa0sjhgH%2BLfplP4kcwD5Xl3xR1wfeHtqWzBHHX8I9SH9Je%2FgGvXxeungIAAA%3D%3D&bn=Imported%20Federal%20Corvette'); }); it('imports a valid v4 build', function() { diff --git a/src/app/components/InternalSlot.jsx b/src/app/components/InternalSlot.jsx index 4ce53f83..fa4f736d 100644 --- a/src/app/components/InternalSlot.jsx +++ b/src/app/components/InternalSlot.jsx @@ -47,13 +47,13 @@ export default class InternalSlot extends Slot { { m.rate ?
{translate('rate')}: {m.rate}{u.kgs}   {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}
: null } { m.getAmmo() ?
{translate('ammunition')}: {formats.gen(m.getAmmo())}
: null } { m.cells ?
{translate('cells')}: {m.cells}
: null } - { m.shieldreinforcement ?
{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} MJ   {translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}
: null } + { m.getShieldReinforcement() ?
{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} MJ   {translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}
: null } { m.repair ?
{translate('repair')}: {m.repair}
: null } { m.getFacingLimit() ?
{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°
: null } { m.getRange() ?
{translate('range')} {formats.f2(m.getRange())}{u.km}
: null } { m.getRangeT() ?
{translate('ranget')} {formats.f1(m.getRangeT())}{u.s}
: null } - { m.spinup ?
{translate('spinup')}: {formats.f1(m.spinup)}{u.s}
: null } - { m.time ?
{translate('time')}: {formats.time(m.time)}
: null } + { m.getSpinup() ?
{translate('spinup')}: {formats.f1(m.getSpinup())}{u.s}
: null } + { m.getTime() ?
{translate('time')}: {formats.getTime()(m.time)}
: null } { m.maximum ?
{translate('max')}: {(m.maximum)}
: null } { m.rangeLS ?
{translate('range')}: {m.rangeLS}{u.Ls}
: null } { m.rangeLS === null ?
∞{u.Ls}
: null } diff --git a/src/app/components/Modification.jsx b/src/app/components/Modification.jsx index c999ff35..357a2df7 100644 --- a/src/app/components/Modification.jsx +++ b/src/app/components/Modification.jsx @@ -50,7 +50,7 @@ export default class Modification extends TranslatedComponent { let m = this.props.m; let ship = this.props.ship; - ship.setModification(m, name, scaledValue); + ship.setModification(m, name, scaledValue, true); this.setState({ value }); this.props.onChange(); diff --git a/src/app/components/ModificationsMenu.jsx b/src/app/components/ModificationsMenu.jsx index 3e0f558d..ee662e8f 100644 --- a/src/app/components/ModificationsMenu.jsx +++ b/src/app/components/ModificationsMenu.jsx @@ -29,6 +29,7 @@ export default class ModificationsMenu extends TranslatedComponent { this.state = this._initState(props, context); this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this); + this._toggleSpecialsMenu = this._toggleSpecialsMenu.bind(this); this._rollWorst = this._rollWorst.bind(this); this._rollRandom = this._rollRandom.bind(this); this._rollAverage = this._rollAverage.bind(this); @@ -44,13 +45,27 @@ export default class ModificationsMenu extends TranslatedComponent { */ _initState(props, context) { let { m, onChange, ship } = props; + const { language, tooltip, termtip } = context; + const translate = language.translate; + // Set up the blueprints let blueprints = []; for (const blueprintName in Modifications.modules[m.grp].blueprints) { for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) { const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade); const key = blueprintName + ':' + grade; - blueprints.push(
{Modifications.blueprints[blueprintName].name} grade {grade}
); + blueprints.push(
{translate(Modifications.blueprints[blueprintName].name + ' grade ' + grade)}
); + } + } + + // Set up the special effects + let specials = []; + if (Modifications.modules[m.grp].specials && Modifications.modules[m.grp].specials.length > 0) { + const close = this._specialSelected.bind(this, null); + specials.push(
{translate('PHRASE_NO_SPECIAL')}
); + for (const specialName of Modifications.modules[m.grp].specials) { + const close = this._specialSelected.bind(this, specialName); + specials.push(
{translate(Modifications.specials[specialName].name)}
); } } @@ -58,11 +73,9 @@ export default class ModificationsMenu extends TranslatedComponent { const modifications = this._setModifications(props); const blueprintMenuOpened = false; + const specialMenuOpened = false; - // Set up the specials for this module - // const specials = _selectSpecials(m); - - return { blueprintMenuOpened, blueprints, modifications }; + return { blueprintMenuOpened, blueprints, modifications, specialMenuOpened, specials }; } /** @@ -106,6 +119,34 @@ export default class ModificationsMenu extends TranslatedComponent { this.props.onChange(); } + /** + * Toggle the specials menu + */ + _toggleSpecialsMenu() { + const specialMenuOpened = !this.state.specialMenuOpened; + this.setState({ specialMenuOpened }); + } + + /** + * Activated when a special is selected + * @param {int} special The name of the selected special + */ + _specialSelected(special) { + const { m } = this.props; + + if (m.blueprint) { + if (special === null) { + m.blueprint.special = null; + } else { + m.blueprint.special = Modifications.specials[special]; + } + } + + const specialMenuOpened = false; + this.setState({ specialMenuOpened, modifications: this._setModifications(this.props) }); + this.props.onChange(); + } + /** * Provide a 'worst' roll within the information we have */ @@ -235,13 +276,13 @@ export default class ModificationsMenu extends TranslatedComponent { * @return {React.Component} List */ render() { - const language = this.context.language; + const { language, tooltip, termtip } = this.context; const translate = language.translate; - const { tooltip, termtip } = this.context; const { m } = this.props; - const { blueprintMenuOpened } = this.state; + const { blueprintMenuOpened, specialMenuOpened } = this.state; const _toggleBlueprintsMenu = this._toggleBlueprintsMenu; + const _toggleSpecialsMenu = this._toggleSpecialsMenu; const _rollBest = this._rollBest; const _rollWorst = this._rollWorst; const _rollAverage = this._rollAverage; @@ -257,31 +298,47 @@ export default class ModificationsMenu extends TranslatedComponent { blueprintLabel = translate('PHRASE_SELECT_BLUEPRINT'); } + let specialLabel; + let haveSpecial = false; + if (m.blueprint && m.blueprint.special) { + specialLabel = m.blueprint.special.name; + } else { + specialLabel = translate('PHRASE_SELECT_SPECIAL'); + } + + const showBlueprintsMenu = blueprintMenuOpened; + const showSpecial = haveBlueprint && this.state.specials.length > 0; + const showSpecialsMenu = specialMenuOpened; + const showRolls = haveBlueprint && !blueprintMenuOpened && !specialMenuOpened; + const showMods = !blueprintMenuOpened && !specialMenuOpened; + return (
e.stopPropagation() } onContextMenu={stopCtxPropagation} > -
{blueprintLabel}
- { blueprintMenuOpened ? this.state.blueprints : '' } - { haveBlueprint ? - - - - - - - - - - - +
{blueprintLabel}
+ { showBlueprintsMenu ? this.state.blueprints : '' } + { showSpecial ?
{specialLabel}
: '' } + { showSpecialsMenu ? this.state.specials : '' } + { showRolls ? +
{ translate('roll') }: { translate('worst') } { translate('average') } { translate('best') } { translate('random') } { translate('reset') }
+ + + + + + + + + +
{ translate('roll') }: { translate('worst') } { translate('average') } { translate('best') } { translate('random') } { translate('reset') }
: '' } - { blueprintMenuOpened ? '' : + { showMods ? { this.state.modifications } - } + : '' }
); } diff --git a/src/app/i18n/en.js b/src/app/i18n/en.js index 8dd9f0ca..3fdbaadf 100644 --- a/src/app/i18n/en.js +++ b/src/app/i18n/en.js @@ -35,6 +35,8 @@ export const terms = { PHRASE_BLUEPRINT_RANDOM: 'Random selection between worst and best primary values for this blueprint', PHRASE_BLUEPRINT_BEST: 'Best primary values for this blueprint', PHRASE_BLUEPRINT_RESET: 'Remove all modifications and blueprint', + PHRASE_SELECT_SPECIAL: 'Click to select an experimental effect', + PHRASE_NO_SPECIAL: 'No experimental effect', HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes', diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index 4ca5d84d..930f4a3d 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -36,75 +36,126 @@ export default class Module { /** * Get a value for a given modification - * @param {Number} name The name of the modification - * @return {object} The value of the modification. If it is a numeric value then it is returned as an integer value scaled so that 1.23% == 123 + * @param {Number} name The name of the modification + * @param {Number} raw True if the value returned should be raw i.e. without the influence of special effects + * @return {object} The value of the modification. If it is a numeric value then it is returned as an integer value scaled so that 1.23% == 123 */ - getModValue(name) { - return this.mods && this.mods[name] ? this.mods[name] : null; + getModValue(name, raw) { + let result = this.mods && this.mods[name] ? this.mods[name] : null; + 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]) { + // this special effect modifies our returned value + const modification = Modifications.modifications[name]; + if (modification.method === 'additive') { + result = result + modifierActions[name]; + } else if (modification.method === 'overwrite') { + result = modifierActions[name]; + } else { + // rate of fire is special, as it's really burst interval. Handle that here + let mod = null; + if (name === 'rof') { + mod = 1 / (1 + modifierActions[name]) - 1; + } else { + mod = modifierActions[name]; + } + result = (((1 + result / 10000) * (1 + mod)) - 1) * 10000; + } + } + } + + // Sanitise the resultant value to 4dp equivalent + return isNaN(result) ? result : Math.round(result); } /** * Set a value for a given modification ID - * @param {Number} name The name of the modification + * @param {Number} name The name of the modification * @param {object} value The value of the modification. If it is a numeric value then it should be an integer scaled so that -2.34% == -234 + * @param {bool} valueiswithspecial true if the value includes the special effect (when coming from a UI component) */ - setModValue(name, value) { + setModValue(name, value, valueiswithspecial) { if (!this.mods) { this.mods = {}; } + if (valueiswithspecial && this.blueprint && this.blueprint.special) { + // This module has a special effect, see if we need to alter the stored value + const modifierActions = Modifications.modifierActions[this.blueprint.special.edname]; + if (modifierActions && modifierActions[name]) { + // This special effect modifies the value being set, so we need to revert it prior to storing the value + const modification = Modifications.modifications[name]; + if (modification.method === 'additive') { + value = value - modifierActions[name]; + } else if (modification.method === 'overwrite') { + value = null; + } else { + // rate of fire is special, as it's really burst interval. Handle that here + let mod = null; + if (name === 'rof') { + mod = 1 / (1 + modifierActions[name]) - 1; + } else { + mod = modifierActions[name]; + } + value = ((value / 10000 + 1) / (1 + mod) - 1) * 10000; + } + } + } if (value == null || value == 0) { delete this.mods[name]; } else { - if (isNaN(value)) { - this.mods[name] = value; - } else { - // Round just to be sure - this.mods[name] = Math.round(value); - } + this.mods[name] = value; } } /** * Helper to obtain a modified value using standard multipliers * @param {String} name the name of the modifier to obtain - * @param {Boolean} additive Optional true if the value is additive rather than multiplicative * @return {Number} the mass of this module */ - _getModifiedValue(name, additive) { - let result = this[name] || (additive ? 0 : null); // Additive NULL === 0 - if (result != null) { - const modification = Modifications.modifications[name]; - if (!modification) { - return result; - } + _getModifiedValue(name) { + const modification = Modifications.modifications[name]; + let result = this[name]; - // 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 - let modValue; - if (modification.type === 'percentage') { - modValue = this.getModValue(name) / 10000; - } else if (modification.type === 'numeric') { - modValue = this.getModValue(name) / 100; + if (!result) { + if (modification && modification.method === 'additive') { + // Additive modifications start at 0 rather than NULL + result = 0; } else { - modValue = this.getModValue(name); + result = null; } - if (modValue) { - if (additive) { - result = result + modValue; + } + + 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 + let modValue; + if (modification.type === 'percentage') { + modValue = this.getModValue(name) / 10000; + } else if (modification.type === 'numeric') { + modValue = this.getModValue(name) / 100; } else { - result = result * (1 + modValue); + modValue = this.getModValue(name); + } + if (modValue) { + if (modification.method === 'additive') { + result = result + modValue; + } else if (modification.method === 'overwrite') { + result = modValue; + } else { + result = result * (1 + modValue); + } } } } else { if (name === 'burst') { // Burst is special, as if it can not exist but have a modification - const modValue = this.getModValue(name) / 100; - return modValue; + 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 - const modValue = this.getModValue(name) / 100; - return modValue; + result = this.getModValue(name) / 100; } } @@ -244,7 +295,7 @@ export default class Module { * @return {Number} the kinetic resistance of this module */ getKineticResistance() { - return this._getModifiedValue('kinres', true); + return this._getModifiedValue('kinres'); } /** @@ -252,7 +303,7 @@ export default class Module { * @return {Number} the thermal resistance of this module */ getThermalResistance() { - return this._getModifiedValue('thermres', true); + return this._getModifiedValue('thermres'); } /** @@ -260,7 +311,7 @@ export default class Module { * @return {Number} the explosive resistance of this module */ getExplosiveResistance() { - return this._getModifiedValue('explres', true); + return this._getModifiedValue('explres'); } /** @@ -671,9 +722,25 @@ export default class Module { /** * Get the shot speed for this module, taking in to account modifications - * @return {string} the damage distribution for this module + * @return {string} the shot speed for this module */ getShotSpeed() { return this._getModifiedValue('shotspeed'); } + + /** + * Get the spinup for this module, taking in to account modifications + * @return {string} the spinup for this module + */ + getSpinup() { + return this._getModifiedValue('spinup'); + } + + /** + * Get the time for this module, taking in to account modifications + * @return {string} the time for this module + */ + getTime() { + return this._getModifiedValue('time'); + } } diff --git a/src/app/shipyard/Ship.js b/src/app/shipyard/Ship.js index 2d2e0f13..aa4803bc 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -438,12 +438,13 @@ export default class Ship { } /** - * Set a modification value - * @param {Object} m The module to change - * @param {Object} name The name of the modification to change + * Set a modification value and update ship stats + * @param {Object} m The module to change + * @param {Object} name The name of the modification to change * @param {Number} value The new value of the modification. The value of the modification is scaled to provide two decimal places of precision in an integer. For example 1.23% is stored as 123 + * @param {bool} sentfromui True if this update was sent from the UI */ - setModification(m, name, value) { + setModification(m, name, value, sentfromui) { if (isNaN(value)) { // Value passed is invalid; reset it to 0 value = 0; @@ -452,58 +453,58 @@ export default class Ship { // Handle special cases if (name === 'pgen') { // Power generation - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.updatePowerGenerated(); } else if (name === 'power') { // Power usage - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.updatePowerUsed(); } else if (name === 'mass') { // Mass let oldMass = m.getMass(); - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); let newMass = m.getMass(); this.unladenMass = this.unladenMass - oldMass + newMass; this.ladenMass = this.ladenMass - oldMass + newMass; this.updateMovement(); this.updateJumpStats(); } else if (name === 'maxfuel') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.updateJumpStats(); } else if (name === 'optmass') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); // Could be for any of thrusters, FSD or shield this.updateMovement(); this.updateJumpStats(); this.recalculateShield(); } else if (name === 'optmul') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); // Could be for any of thrusters, FSD or shield this.updateMovement(); this.updateJumpStats(); this.recalculateShield(); } else if (name === 'shieldboost') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.recalculateShield(); } else if (name === 'hullboost' || name === 'hullreinforcement' || name === 'modulereinforcement') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.recalculateArmour(); } else if (name === 'shieldreinforcement') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.recalculateShieldCells(); } else if (name === 'burst' || name == 'burstrof' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); this.recalculateDps(); this.recalculateHps(); this.recalculateEps(); } else if (name === 'explres' || name === 'kinres' || name === 'thermres') { - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); // Could be for shields or armour this.recalculateArmour(); this.recalculateShield(); } else { // Generic - m.setModValue(name, value); + m.setModValue(name, value, sentfromui); } } @@ -1376,7 +1377,7 @@ export default class Ship { for (let modKey in this.bulkheads.m.mods) { // Filter out invalid modifications if (Modifications.modules['bh'] && Modifications.modules['bh'].modifications.indexOf(modKey) != -1) { - bulkheadMods.push({ id: Modifications.modifications[modKey].id, value: this.bulkheads.m.getModValue(modKey) }); + bulkheadMods.push({ id: Modifications.modifications[modKey].id, value: this.bulkheads.m.getModValue(modKey, true) }); } } bulkheadBlueprint = this.bulkheads.m.blueprint; @@ -1391,7 +1392,7 @@ export default class Ship { for (let modKey in slot.m.mods) { // Filter out invalid modifications if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { - slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) }); + slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) }); } } } @@ -1406,7 +1407,7 @@ export default class Ship { for (let modKey in slot.m.mods) { // Filter out invalid modifications if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { - slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) }); + slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) }); } } } @@ -1421,7 +1422,7 @@ export default class Ship { for (let modKey in slot.m.mods) { // Filter out invalid modifications if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { - slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) }); + slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) }); } } } diff --git a/src/app/utils/CompanionApiUtils.js b/src/app/utils/CompanionApiUtils.js index e1cf0d1a..674ef674 100644 --- a/src/app/utils/CompanionApiUtils.js +++ b/src/app/utils/CompanionApiUtils.js @@ -308,6 +308,9 @@ function _addModifications(module, modifiers, blueprint, grade) { } else if (modifiers.modifiers[i].name === 'mod_weapon_falloffrange_from_range') { // Obtain the falloff value directly from the range module.setModValue('fallofffromrange', 1); + } else if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) { + // We don't add special effects directly, but keep a note of them so they can be added when fetching values + special = Modifications.specials[modifiers.modifiers[i].name]; } else { // Look up the modifiers to find what we need to do const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name]; @@ -327,11 +330,6 @@ function _addModifications(module, modifiers, blueprint, grade) { } } } - - // Note the special if present - if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) { - special = Modifications.specials[modifiers.modifiers[i].name]; - } } // Add the blueprint ID, grade and special