Compare commits

..

13 Commits
2.2.4 ... 2.2.5

Author SHA1 Message Date
Cmdr McDonald
0a37b36ec2 Merge branch 'release/2.2.5' 2016-12-03 15:48:45 +00:00
Cmdr McDonald
85e6796e88 Bump version 2016-12-03 15:48:39 +00:00
Cmdr McDonald
fa1ef47b71 Add note to disable ghostery in error situations 2016-12-01 13:26:33 +00:00
Cmdr McDonald
f31e3c09f4 Merge branch 'feature/rebalance' into develop 2016-12-01 10:28:21 +00:00
Cmdr McDonald
e6ab536601 Merge branch 'feature/rebalance' of https://github.com/EDCD/coriolis into feature/rebalance 2016-12-01 10:28:08 +00:00
Cmdr McDonald
5bced9fe56 Bump version number 2016-11-30 15:09:25 +00:00
Cmdr McDonald
67742060d3 Merge branch 'feature/burst' into develop 2016-11-30 15:09:04 +00:00
Cmdr McDonald
ca2136544c Handle unmodifiable values 2016-11-30 15:08:32 +00:00
Cmdr McDonald
ee19e9af50 Lint 2016-11-30 14:56:33 +00:00
Cmdr McDonald
f457fd0bff Fixes for burst calculations 2016-11-30 14:51:19 +00:00
Cmdr McDonald
c1ce07e039 Calculate rate of fire for multi-burst weapons 2016-11-30 12:19:40 +00:00
Cmdr McDonald
c8d1536f77 Bump version number 2016-11-29 13:53:23 +00:00
Cmdr McDonald
231ad4af59 Merge branch 'release/2.2.4' into develop 2016-11-28 16:54:35 +00:00
13 changed files with 146 additions and 58 deletions

View File

@@ -1,3 +1,12 @@
#2.2.5
* Calculate rate of fire for multi-burst weapons
* Add note to disable ghostery in error situation
* Use coriolis-data 2.2.5:
* Fix incorrect ID for emissive munitions special
* Fix rate of fire for burst lasers
* Add fragment cannon modifications
* Fix internal name of dazzle shell
#2.2.4 #2.2.4
* Add shortlink for outfitting page * Add shortlink for outfitting page
* Use coriolis-data 2.2.4: * Use coriolis-data 2.2.4:

View File

@@ -271,7 +271,7 @@
"totalExplDpe": 0, "totalExplDpe": 0,
"totalExplDps": 0, "totalExplDps": 0,
"totalExplSDps": 0, "totalExplSDps": 0,
"totalHps": 33.28, "totalHps": 33.62,
"totalKinDpe": 103.97, "totalKinDpe": 103.97,
"totalKinDps": 28.92, "totalKinDps": 28.92,
"totalKinSDps": 21.23, "totalKinSDps": 21.23,

View File

@@ -1,6 +1,6 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "2.2.4", "version": "2.2.5",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/EDCD/coriolis" "url": "https://github.com/EDCD/coriolis"

View File

@@ -8,7 +8,7 @@ import Header from './components/Header';
import Tooltip from './components/Tooltip'; import Tooltip from './components/Tooltip';
import ModalImport from './components/ModalImport'; import ModalImport from './components/ModalImport';
import * as CompanionApiUtils from './utils/CompanionApiUtils'; import * as CompanionApiUtils from './utils/CompanionApiUtils';
import { outfitURL } from './utils/UrlGenerators' import { outfitURL } from './utils/UrlGenerators';
import AboutPage from './pages/AboutPage'; import AboutPage from './pages/AboutPage';
import NotFoundPage from './pages/NotFoundPage'; import NotFoundPage from './pages/NotFoundPage';

View File

@@ -72,7 +72,7 @@ export default class ComparisonTable extends TranslatedComponent {
* @return {React.Component} Table row * @return {React.Component} Table row
*/ */
_buildRow(build, facets, formats, units) { _buildRow(build, facets, formats, units) {
let url = outfitURL(build.id, build.toString(), build.buildName) let url = outfitURL(build.id, build.toString(), build.buildName);
let cells = [ let cells = [
<td key='s' className='tl'><Link href={url}>{build.name}</Link></td>, <td key='s' className='tl'><Link href={url}>{build.name}</Link></td>,
<td key='bn' className='tl'><Link href={url}>{build.buildName}</Link></td> <td key='bn' className='tl'><Link href={url}>{build.buildName}</Link></td>

View File

@@ -48,22 +48,22 @@ export default class HardpointSlot extends Slot {
let modTT = translate('modified'); let modTT = translate('modified');
if (m && m.blueprint) { if (m && m.blueprint) {
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
if (m.blueprint.special && m.blueprint.special.id) { if (m.blueprint.special && m.blueprint.special.id) {
modTT += ', ' + translate(m.blueprint.special.name); modTT += ', ' + translate(m.blueprint.special.name);
} }
} }
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}> return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
<div className={'cb'}> <div className={'cb'}>
<div className={'l'}> <div className={'l'}>
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''} {m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''}
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''} {m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''}
{m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''} {m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''}
{m.getDamageType() && m.getDamageType().match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''} {m.getDamageType() && m.getDamageType().match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''}
{m.getDamageType() && m.getDamageType().match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''} {m.getDamageType() && m.getDamageType().match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''}
{m.getDamageType() && m.getDamageType().match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''} {m.getDamageType() && m.getDamageType().match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''}
{classRating} {translate(m.name || m.grp)}{ m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null } {classRating} {translate(m.name || m.grp)}{ m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }
</div> </div>
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div> <div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
</div> </div>

View File

@@ -346,6 +346,7 @@ export default class ModalImport extends TranslatedComponent {
} }
} }
} catch (e) { } catch (e) {
// console.log(e.stack);
this.setState({ errorMsg: (typeof e == 'string') ? e : 'Cannot Parse the data!' }); this.setState({ errorMsg: (typeof e == 'string') ? e : 'Cannot Parse the data!' });
return; return;
} }

View File

@@ -63,9 +63,24 @@ export default class Modification extends TranslatedComponent {
let translate = this.context.language.translate; let translate = this.context.language.translate;
let name = this.props.name; let name = this.props.name;
if (name === 'type') {
// We don't show type
return null;
}
let symbol;
if (name === 'jitter') {
symbol = '°';
} else if (name !== 'burst') {
symbol = '%';
}
if (symbol) {
symbol = ' (' + symbol + ')';
}
return ( return (
<div className={'cb'} key={name}> <div className={'cb'} key={name}>
<div className={'cb'}>{translate(name)}{name === 'jitter' ? ' (°)' : ' (%)'}</div> <div className={'cb'}>{translate(name)}{symbol}</div>
<NumberEditor className={'cb'} style={{ width: '90%', textAlign: 'center' }} step={0.01} stepModifier={1} decimals={2} value={this.state.value} onValueChange={this._updateValue.bind(this)} /> <NumberEditor className={'cb'} style={{ width: '90%', textAlign: 'center' }} step={0.01} stepModifier={1} decimals={2} value={this.state.value} onValueChange={this._updateValue.bind(this)} />
</div> </div>
); );

View File

@@ -42,6 +42,7 @@ export default class ErrorDetails extends React.Component {
return <div className='error'> return <div className='error'>
<h1>Jameson, we have a problem..</h1> <h1>Jameson, we have a problem..</h1>
<h1><small>{error.message}</small></h1> <h1><small>{error.message}</small></h1>
<div>Please note that this site uses Google Analytics to track performance and usage. If you are blocking cookies, for example using Ghostery, please disable blocking for this site and try again.</div>
{content} {content}
</div>; </div>;
} }

View File

@@ -1,5 +1,6 @@
import * as ModuleUtils from './ModuleUtils'; import * as ModuleUtils from './ModuleUtils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { Modifications } from 'coriolis-data/dist';
/** /**
* Module - active module in a ship's buildout * Module - active module in a ship's buildout
@@ -65,8 +66,20 @@ export default class Module {
_getModifiedValue(name, additive) { _getModifiedValue(name, additive) {
let result = this[name] || (additive ? 0 : null); // Additive NULL === 0 let result = this[name] || (additive ? 0 : null); // Additive NULL === 0
if (result != null) { if (result != null) {
// Jitter is special, being the only non-percentage value (it is in fact degrees) const modification = Modifications.modifications[name];
const modValue = name === 'jitter' ? this.getModValue(name) / 100 : this.getModValue(name) / 10000; if (!modification) {
return result;
}
// 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 {
modValue = this.getModValue(name);
}
if (modValue) { if (modValue) {
if (additive) { if (additive) {
result = result + modValue; result = result + modValue;
@@ -74,7 +87,18 @@ export default class Module {
result = result * (1 + modValue); 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;
} 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;
}
} }
return result; return result;
} }
@@ -425,7 +449,7 @@ export default class Module {
getDps() { getDps() {
// DPS is a synthetic value // DPS is a synthetic value
let damage = this.getDamage(); let damage = this.getDamage();
let rpshot = this.getRoundsPerShot() || 1; let rpshot = this.roundspershot || 1;
let rof = this.getRoF() || 1; let rof = this.getRoF() || 1;
return damage * rpshot * rof; return damage * rpshot * rof;
@@ -438,7 +462,7 @@ export default class Module {
getEps() { getEps() {
// EPS is a synthetic value // EPS is a synthetic value
let distdraw = this.getDistDraw(); let distdraw = this.getDistDraw();
let rpshot = this.getRoundsPerShot() || 1; let rpshot = this.roundspershot || 1;
let rof = this.getRoF() || 1; let rof = this.getRoF() || 1;
return distdraw * rpshot * rof; return distdraw * rpshot * rof;
@@ -451,7 +475,7 @@ export default class Module {
getHps() { getHps() {
// HPS is a synthetic value // HPS is a synthetic value
let heat = this.getThermalLoad(); let heat = this.getThermalLoad();
let rpshot = this.getRoundsPerShot() || 1; let rpshot = this.roundspershot || 1;
let rof = this.getRoF() || 1; let rof = this.getRoF() || 1;
return heat * rpshot * rof; return heat * rpshot * rof;
@@ -482,11 +506,35 @@ export default class Module {
} }
/** /**
* Get the rate of fire for this module, taking in to account modifications * Get the burst size for this module, taking in to account modifications
* @return {Number} the burst size of this module
*/
getBurst() {
return this._getModifiedValue('burst');
}
/**
* Get the burst rate of fire for this module, taking in to account modifications
* @return {Number} the burst rate of fire of this module
*/
getBurstRoF() {
return this._getModifiedValue('burstrof');
}
/**
* Get the rate of fire for this module, taking in to account modifications.
* 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'
* @return {Number} the rate of fire for this module * @return {Number} the rate of fire for this module
*/ */
getRoF() { getRoF() {
return this._getModifiedValue('rof'); const burst = this.getBurst() || 1;
const burstRoF = this.getBurstRoF() || 1;
const intRoF = this._getModifiedValue('rof');
return burst / (((burst - 1) / burstRoF) + 1 / intRoF);
} }
/** /**

View File

@@ -8,7 +8,7 @@ import { outfitURL } from '../utils/UrlGenerators';
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank']; const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
const STANDARD_GROUPS = {'powerPlant': 'pp', 'thrusters': 't', 'frameShiftDrive': 'fsd', 'lifeSupport': 'ls', 'powerDistributor': 'pd', 'sensors': 's', 'fuelTank': 'ft'}; const STANDARD_GROUPS = { 'powerPlant': 'pp', 'thrusters': 't', 'frameShiftDrive': 'fsd', 'lifeSupport': 'ls', 'powerDistributor': 'pd', 'sensors': 's', 'fuelTank': 'ft' };
/** /**
* Generates ship-loadout JSON Schema standard object * Generates ship-loadout JSON Schema standard object

View File

@@ -458,7 +458,7 @@ export default class Ship {
} else if (name === 'shieldreinforcement') { } else if (name === 'shieldreinforcement') {
m.setModValue(name, value); m.setModValue(name, value);
this.recalculateShieldCells(); this.recalculateShieldCells();
} else if (name === 'burst' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') { } 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);
this.recalculateDps(); this.recalculateDps();
this.recalculateHps(); this.recalculateHps();
@@ -1260,7 +1260,7 @@ export default class Ship {
let modElements = mods[j].split(':'); let modElements = mods[j].split(':');
if (modElements[0].match('[0-9]+')) { if (modElements[0].match('[0-9]+')) {
const modification = _.find(Modifications.modifications, function(o) { return o.id === modElements[0]; }); const modification = _.find(Modifications.modifications, function(o) { return o.id === modElements[0]; });
if (modification != null) arr[i][modification.name] = Number(modElements[1]); if (modification != null) arr[i][modification.name] = Number(modElements[1]);
} else { } else {
arr[i][modElements[0]] = Number(modElements[1]); arr[i][modElements[0]] = Number(modElements[1]);
} }
@@ -1297,7 +1297,7 @@ export default class Ship {
bulkheadBlueprint = this.bulkheads.m.blueprint; bulkheadBlueprint = this.bulkheads.m.blueprint;
} }
slots.push(bulkheadMods); slots.push(bulkheadMods);
blueprints.push(bulkheadBlueprint) blueprints.push(bulkheadBlueprint);
specials.push(bulkheadBlueprint ? bulkheadBlueprint.special : null); specials.push(bulkheadBlueprint ? bulkheadBlueprint.special : null);
for (let slot of this.standard) { for (let slot of this.standard) {
@@ -1356,7 +1356,7 @@ export default class Ship {
for (let special of specials) { for (let special of specials) {
if (special) { if (special) {
// Length is 5 for each special // Length is 5 for each special
bufsize += 5; bufsize += 5;
} }
} }
@@ -1376,20 +1376,20 @@ export default class Ship {
buffer.writeInt8(MODIFICATION_ID_GRADE, curpos++); buffer.writeInt8(MODIFICATION_ID_GRADE, curpos++);
buffer.writeInt32LE(blueprints[i].grade, curpos); buffer.writeInt32LE(blueprints[i].grade, curpos);
curpos += 4; curpos += 4;
} }
if (specials[i]) { if (specials[i]) {
buffer.writeInt8(MODIFICATION_ID_SPECIAL, curpos++); buffer.writeInt8(MODIFICATION_ID_SPECIAL, curpos++);
buffer.writeInt32LE(specials[i].id, curpos); buffer.writeInt32LE(specials[i].id, curpos);
curpos += 4; curpos += 4;
} }
for (let slotMod of slot) { for (let slotMod of slot) {
buffer.writeInt8(slotMod.id, curpos++); buffer.writeInt8(slotMod.id, curpos++);
if (isNaN(slotMod.value)) { if (isNaN(slotMod.value)) {
// Need to write the string with exactly four characters, so pad with whitespace // Need to write the string with exactly four characters, so pad with whitespace
buffer.write((" " + slotMod.value).slice(-4), curpos, 4); buffer.write((' ' + slotMod.value).slice(-4), curpos, 4);
} else { } else {
buffer.writeInt32LE(slotMod.value, curpos); buffer.writeInt32LE(slotMod.value, curpos);
} }
// const modification = _.find(Modifications.modifications, function(o) { return o.id === slotMod.id; }); // const modification = _.find(Modifications.modifications, function(o) { return o.id === slotMod.id; });
// console.log('ENCODE Slot ' + i + ': ' + modification.name + ' = ' + slotMod.value); // console.log('ENCODE Slot ' + i + ': ' + modification.name + ' = ' + slotMod.value);
curpos += 4; curpos += 4;
@@ -1414,7 +1414,7 @@ export default class Ship {
* See updateModificationsString() for details of the structure. * See updateModificationsString() for details of the structure.
* @param {String} buffer Buffer holding modification info * @param {String} buffer Buffer holding modification info
* @param {Array} modArr Modification array * @param {Array} modArr Modification array
* @param {Array} bluprintArr Blueprint array * @param {Array} blueprintArr Blueprint array
*/ */
decodeModificationsStruct(buffer, modArr, blueprintArr) { decodeModificationsStruct(buffer, modArr, blueprintArr) {
let curpos = 0; let curpos = 0;
@@ -1428,22 +1428,22 @@ export default class Ship {
if (modificationId === 40) { if (modificationId === 40) {
// Type is special, in that it's a character string // Type is special, in that it's a character string
modificationValue = buffer.toString('utf8', curpos, curpos + 4).trim(); modificationValue = buffer.toString('utf8', curpos, curpos + 4).trim();
} else { } else {
modificationValue = buffer.readInt32LE(curpos); modificationValue = buffer.readInt32LE(curpos);
} }
curpos += 4; curpos += 4;
// There are a number of 'special' modification IDs, check for them here // There are a number of 'special' modification IDs, check for them here
if (modificationId === MODIFICATION_ID_BLUEPRINT) { if (modificationId === MODIFICATION_ID_BLUEPRINT) {
blueprint = Object.assign(blueprint, _.find(Modifications.blueprints, function(o) { return o.id === modificationValue; })); blueprint = Object.assign(blueprint, _.find(Modifications.blueprints, function(o) { return o.id === modificationValue; }));
} else if (modificationId === MODIFICATION_ID_GRADE) { } else if (modificationId === MODIFICATION_ID_GRADE) {
blueprint.grade = modificationValue; blueprint.grade = modificationValue;
} else if (modificationId === MODIFICATION_ID_SPECIAL) { } else if (modificationId === MODIFICATION_ID_SPECIAL) {
blueprint.special = _.find(Modifications.specials, function(o) { return o.id === modificationValue; }); blueprint.special = _.find(Modifications.specials, function(o) { return o.id === modificationValue; });
} else { } else {
const modification = _.find(Modifications.modifications, function(o) { return o.id === modificationId; }); const modification = _.find(Modifications.modifications, function(o) { return o.id === modificationId; });
// console.log('DECODE Slot ' + slot + ': ' + modification.name + ' = ' + modificationValue); // console.log('DECODE Slot ' + slot + ': ' + modification.name + ' = ' + modificationValue);
modifications[modification.name] = modificationValue; modifications[modification.name] = modificationValue;
} }
modificationId = buffer.readInt8(curpos++); modificationId = buffer.readInt8(curpos++);
} }
modArr[slot] = modifications; modArr[slot] = modifications;

View File

@@ -277,29 +277,43 @@ export function shipFromJson(json) {
function _addModifications(module, modifiers, blueprint, grade) { function _addModifications(module, modifiers, blueprint, grade) {
if (!modifiers || !modifiers.modifiers) return; if (!modifiers || !modifiers.modifiers) return;
var special; let special;
for (const i in modifiers.modifiers) { for (const i in modifiers.modifiers) {
// Look up the modifiers to find what we need to do // Some special modifications
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name]; if (modifiers.modifiers[i].name === 'mod_weapon_clip_size_override') {
const value = modifiers.modifiers[i].value; // This is a numeric addition to the clip size, but we need to work it out in terms of being a percentage so
// that it works the same as other modifications
const origClip = module.clip || 1;
module.setModValue('clip', ((modifiers.modifiers[i].value - origClip) / origClip) * 10000);
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_size') {
// This is an absolute number that acts as an override
module.setModValue('burst', modifiers.modifiers[i].value * 100);
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_rof') {
// For some reason this is a non-normalised percentage (i.e. 12.23% is 12.23 value rather than 0.1223 as everywhere else), so fix that here
module.setModValue('burstrof', modifiers.modifiers[i].value * 100);
} else {
// Look up the modifiers to find what we need to do
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
const value = modifiers.modifiers[i].value;
// Carry out the required changes // Carry out the required changes
for (const action in modifierActions) { for (const action in modifierActions) {
if (isNaN(modifierActions[action])) { if (isNaN(modifierActions[action])) {
module.setModValue(action, modifierActions[action]); module.setModValue(action, modifierActions[action]);
} else { } else {
const actionValue = modifierActions[action] * value; const actionValue = modifierActions[action] * value;
let mod = module.getModValue(action) / 10000; let mod = module.getModValue(action) / 10000;
if (!mod) { if (!mod) {
mod = 0; mod = 0;
}
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
} }
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
} }
} }
// Note the special if present // Note the special if present
if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) { if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) {
special = Modifications.specials[modifiers.modifiers[i].name]; special = Modifications.specials[modifiers.modifiers[i].name];
} }
} }