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 ?
-
-
-
- | { translate('roll') }: |
- { translate('worst') } |
- { translate('average') } |
- { translate('best') } |
- { translate('random') } |
- { translate('reset') } |
-
-
+ {blueprintLabel}
+ { showBlueprintsMenu ? this.state.blueprints : '' }
+ { showSpecial ? {specialLabel}
: '' }
+ { showSpecialsMenu ? this.state.specials : '' }
+ { showRolls ?
+
+
+
+ | { 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