Add specials

This commit is contained in:
Cmdr McDonald
2017-01-26 16:06:29 +00:00
parent 0ae59c5e48
commit c1ddecfd3e
9 changed files with 220 additions and 94 deletions

View File

@@ -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

View File

@@ -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() {

View File

@@ -47,13 +47,13 @@ export default class InternalSlot extends Slot {
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs}&nbsp;&nbsp;&nbsp;{translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.gen(m.getAmmo())}</div> : null }
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
{ m.shieldreinforcement ? <div className={'l'}>{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} <u>MJ</u>&nbsp;&nbsp;&nbsp;{translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}</div> : null }
{ m.getShieldReinforcement() ? <div className={'l'}>{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} <u>MJ</u>&nbsp;&nbsp;&nbsp;{translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}</div> : null }
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
{ m.getFacingLimit() ? <div className={'l'}>{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°</div> : null }
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f2(m.getRange())}{u.km}</div> : null }
{ m.getRangeT() ? <div className={'l'}>{translate('ranget')} {formats.f1(m.getRangeT())}{u.s}</div> : null }
{ m.spinup ? <div className={'l'}>{translate('spinup')}: {formats.f1(m.spinup)}{u.s}</div> : null }
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null }
{ m.getSpinup() ? <div className={'l'}>{translate('spinup')}: {formats.f1(m.getSpinup())}{u.s}</div> : null }
{ m.getTime() ? <div className={'l'}>{translate('time')}: {formats.getTime()(m.time)}</div> : null }
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
{ m.rangeLS === null ? <div className={'l'}>{u.Ls}</div> : null }

View File

@@ -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();

View File

@@ -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(<div style={{ cursor: 'pointer' }} key={ key } onClick={ close }>{Modifications.blueprints[blueprintName].name} grade {grade}</div>);
blueprints.push(<div style={{ cursor: 'pointer' }} key={ key } onClick={ close }>{translate(Modifications.blueprints[blueprintName].name + ' grade ' + grade)}</div>);
}
}
// 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(<div style={{ cursor: 'pointer' }} key={ 'none' } onClick={ close }>{translate('PHRASE_NO_SPECIAL')}</div>);
for (const specialName of Modifications.modules[m.grp].specials) {
const close = this._specialSelected.bind(this, specialName);
specials.push(<div style={{ cursor: 'pointer' }} key={ specialName } onClick={ close }>{translate(Modifications.specials[specialName].name)}</div>);
}
}
@@ -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 (
<div
className={cn('select', this.props.className)}
onClick={(e) => e.stopPropagation() }
onContextMenu={stopCtxPropagation}
>
<div className={ cn('section-menu', { selected: true })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
{ blueprintMenuOpened ? this.state.blueprints : '' }
{ haveBlueprint ?
<table style={{ width: '100%', backgroundColor: 'transparent' }}>
<tbody>
<tr>
<td> { translate('roll') }: </td>
<td style={{ cursor: 'pointer' }} onClick={_rollWorst} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('worst') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollAverage}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_AVERAGE')} onMouseOut={tooltip.bind(null, null)}> { translate('average') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollBest}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('best') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollRandom} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RANDOM')} onMouseOut={tooltip.bind(null, null)}> { translate('random') } </td>
<td style={{ cursor: 'pointer' }} onClick={_reset}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RESET')} onMouseOut={tooltip.bind(null, null)}> { translate('reset') } </td>
</tr>
</tbody>
<div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
{ showBlueprintsMenu ? this.state.blueprints : '' }
{ showSpecial ? <div className={ cn('section-menu', { selected: specialMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleSpecialsMenu}>{specialLabel}</div> : '' }
{ showSpecialsMenu ? this.state.specials : '' }
{ showRolls ?
<table style={{ width: '100%', backgroundColor: 'transparent' }}>
<tbody>
<tr>
<td> { translate('roll') }: </td>
<td style={{ cursor: 'pointer' }} onClick={_rollWorst} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('worst') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollAverage}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_AVERAGE')} onMouseOut={tooltip.bind(null, null)}> { translate('average') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollBest}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('best') } </td>
<td style={{ cursor: 'pointer' }} onClick={_rollRandom} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RANDOM')} onMouseOut={tooltip.bind(null, null)}> { translate('random') } </td>
<td style={{ cursor: 'pointer' }} onClick={_reset}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RESET')} onMouseOut={tooltip.bind(null, null)}> { translate('reset') } </td>
</tr>
</tbody>
</table> : '' }
{ blueprintMenuOpened ? '' :
{ showMods ?
<span onMouseOver={termtip.bind(null, 'HELP_MODIFICATIONS_MENU')} onMouseOut={tooltip.bind(null, null)} >
{ this.state.modifications }
</span> }
</span> : '' }
</div>
);
}

View File

@@ -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',

View File

@@ -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');
}
}

View File

@@ -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) });
}
}
}

View File

@@ -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