Compare commits

...

31 Commits

Author SHA1 Message Date
Cmdr McDonald
ca0c9675b3 Merge branch 'release/2.2.12' 2017-01-29 08:27:24 +00:00
Cmdr McDonald
491899fe49 Package bump 2017-01-29 08:27:17 +00:00
Cmdr McDonald
cc22a89ad6 Merge branch 'feature/specials' into develop 2017-01-29 08:26:34 +00:00
Cmdr McDonald
d389114189 Remove extraneous functions 2017-01-28 20:40:58 +00:00
Cmdr McDonald
9d0f7a166b Don't show both power generation and power draw in diffDetails 2017-01-27 22:23:36 +00:00
Cmdr McDonald
c344d56d48 Merge branch 'feature/specials' of https://github.com/EDCD/coriolis into feature/specials 2017-01-27 21:34:33 +00:00
Cmdr McDonald
eb5d0e868c Remove logging 2017-01-27 21:34:27 +00:00
Cmdr McDonald
c28f22a78b Add units for time 2017-01-27 21:34:27 +00:00
Cmdr McDonald
e2b22dd4ca Alter shortlink hotkey - for #58 2017-01-27 21:32:07 +00:00
Cmdr McDonald
f5ecccec48 Add weapon mods to damage dealt 2017-01-27 21:32:07 +00:00
Cmdr McDonald
7c8eee4707 Add package info 2017-01-27 21:32:07 +00:00
Cmdr McDonald
99e251fd4b Fix missing break in case 2017-01-27 21:32:07 +00:00
Cmdr McDonald
c1ddecfd3e Add specials 2017-01-27 21:32:07 +00:00
Cmdr McDonald
0ae59c5e48 Remove old reference to coriolis.io 2017-01-27 21:32:07 +00:00
Cmdr McDonald
eb76040b08 Remove logging 2017-01-27 21:31:05 +00:00
Cmdr McDonald
7698cb75e9 Add units for time 2017-01-27 21:30:15 +00:00
Cmdr McDonald
bd7139c703 Merge branch 'feature/specials' of https://github.com/EDCD/coriolis into feature/specials 2017-01-27 09:54:26 +00:00
Cmdr McDonald
c9b9404ba1 Alter shortlink hotkey - for #58 2017-01-27 09:54:17 +00:00
Cmdr McDonald
84ff013a9e Add weapon mods to damage dealt 2017-01-27 09:54:17 +00:00
Cmdr McDonald
d2bcf6cd71 Add package info 2017-01-27 09:54:17 +00:00
Cmdr McDonald
e52c6730f4 Fix missing break in case 2017-01-27 09:54:17 +00:00
Cmdr McDonald
e448b3cb0a Add specials 2017-01-27 09:54:17 +00:00
Cmdr McDonald
705f3158aa Remove old reference to coriolis.io 2017-01-27 09:54:17 +00:00
Cmdr McDonald
f4789717fe Alter shortlink hotkey - for #58 2017-01-27 09:54:08 +00:00
Cmdr McDonald
93e69f215b Add weapon mods to damage dealt 2017-01-27 09:46:32 +00:00
Cmdr McDonald
d04e662de4 Merge branch 'hotfix/2.2.11b' into develop 2017-01-27 08:14:37 +00:00
Cmdr McDonald
db376829f5 Add package info 2017-01-27 07:56:50 +00:00
Cmdr McDonald
79a31fd992 Fix missing break in case 2017-01-26 18:01:22 +00:00
Cmdr McDonald
094f3aa3e2 Add specials 2017-01-26 16:06:29 +00:00
Cmdr McDonald
41d51743d3 Remove old reference to coriolis.io 2017-01-26 14:38:23 +00:00
Cmdr McDonald
cf741d18ed Merge branch 'release/2.2.11' into develop 2017-01-25 19:46:52 +00:00
22 changed files with 266 additions and 143 deletions

View File

@@ -1,3 +1,13 @@
#2.2.12
* Tidy up old references to coriolis.io
* Add ability to add and remove special effects to weapon modifications
* Add weapon engineering information to Damage Dealt section
* Change shortcut for link from ctrl-l to ctrl-o to avoid clash with location bar
* Only show one of power generation or draw in tooltips, according to module
* Use coriolis-data 2.2.12:
* Add special effects for each blueprint
* Add IDs for most Powerplay modules
#2.2.11 #2.2.11
* Add help system and initial help file * Add help system and initial help file
* Make absolute damage visible * Make absolute damage visible

View File

@@ -238,7 +238,7 @@ describe('Import Modal', function() {
expect(modal.state.singleBuild).toBe(true); expect(modal.state.singleBuild).toBe(true);
clickProceed(); clickProceed();
expect(MockRouter.go.mock.calls.length).toBe(1); 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() { it('imports a valid v4 build', function() {

View File

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

View File

@@ -174,11 +174,12 @@ export default class Coriolis extends React.Component {
this._showModal(<ModalImport />); this._showModal(<ModalImport />);
} }
break; break;
case 76: // 'l' case 79: // 'o'
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + l if (e.ctrlKey || e.metaKey) { // CTRL/CMD + o
e.preventDefault(); e.preventDefault();
this._showModal(<ModalPermalink url={window.location.href}/>); this._showModal(<ModalPermalink url={window.location.href}/>);
} }
break;
case 83: // 's' case 83: // 's'
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + s if (e.ctrlKey || e.metaKey) { // CTRL/CMD + s
e.preventDefault(); e.preventDefault();

View File

@@ -103,6 +103,8 @@ export default class DamageDealt extends TranslatedComponent {
* @return {boolean} Returns the per-weapon damage * @return {boolean} Returns the per-weapon damage
*/ */
_calcWeapons(ship, against, range) { _calcWeapons(ship, against, range) {
const translate = this.context.language.translate;
// Tidy up the range so that it's to 4 decimal places // Tidy up the range so that it's to 4 decimal places
range = Math.round(10000 * range) / 10000; range = Math.round(10000 * range) / 10000;
@@ -137,6 +139,13 @@ export default class DamageDealt extends TranslatedComponent {
} }
} }
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`; const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
let engineering;
if (m.blueprint && m.blueprint.name) {
engineering = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
if (m.blueprint.special && m.blueprint.special.id) {
engineering += ', ' + translate(m.blueprint.special.name);
}
}
const effectivenessShields = dropoff; const effectivenessShields = dropoff;
const effectiveDpsShields = m.getDps() * effectivenessShields; const effectiveDpsShields = m.getDps() * effectivenessShields;
const effectiveSDpsShields = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessShields : effectiveDpsShields); const effectiveSDpsShields = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessShields : effectiveDpsShields);
@@ -154,6 +163,7 @@ export default class DamageDealt extends TranslatedComponent {
mount: m.mount, mount: m.mount,
name: m.name || m.grp, name: m.name || m.grp,
classRating, classRating,
engineering,
effectiveDpsShields, effectiveDpsShields,
effectiveSDpsShields, effectiveSDpsShields,
effectivenessShields, effectivenessShields,
@@ -163,9 +173,7 @@ export default class DamageDealt extends TranslatedComponent {
} }
} }
} }
console.log('total dps is ' + totalDps);
totals.effectivenessShields = totalDps == 0 ? 0 : totals.effectiveDpsShields / totalDps; totals.effectivenessShields = totalDps == 0 ? 0 : totals.effectiveDpsShields / totalDps;
console.log('total effective dps shields is ' + totals.effectiveDpsShields);
totals.effectivenessHull = totalDps == 0 ? 0 : totals.effectiveDpsHull / totalDps; totals.effectivenessHull = totalDps == 0 ? 0 : totals.effectiveDpsHull / totalDps;
return { weapons, totals }; return { weapons, totals };
@@ -249,6 +257,7 @@ console.log('total effective dps shields is ' + totals.effectiveDpsShields);
{weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null} {weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null}
{weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null} {weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
{weapon.classRating} {translate(weapon.name)} {weapon.classRating} {translate(weapon.name)}
{weapon.engineering ? ' (' + weapon.engineering + ')' : null }
</td> </td>
<td className='ri'>{formats.round1(weapon.effectiveDpsShields)}</td> <td className='ri'>{formats.round1(weapon.effectiveDpsShields)}</td>
<td className='ri'>{formats.round1(weapon.effectiveSDpsShields)}</td> <td className='ri'>{formats.round1(weapon.effectiveSDpsShields)}</td>

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.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.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.gen(m.getAmmo())}</div> : null }
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</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.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
{ m.getFacingLimit() ? <div className={'l'}>{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°</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.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.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.getSpinup() ? <div className={'l'}>{translate('spinup')}: {formats.f1(m.getSpinup())}{u.s}</div> : null }
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null } { m.getTime() ? <div className={'l'}>{translate('time')}: {formats.time(m.getTime())}</div> : null }
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</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 ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
{ m.rangeLS === null ? <div className={'l'}>{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 m = this.props.m;
let ship = this.props.ship; let ship = this.props.ship;
ship.setModification(m, name, scaledValue); ship.setModification(m, name, scaledValue, true);
this.setState({ value }); this.setState({ value });
this.props.onChange(); this.props.onChange();

View File

@@ -29,6 +29,7 @@ export default class ModificationsMenu extends TranslatedComponent {
this.state = this._initState(props, context); this.state = this._initState(props, context);
this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this); this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this);
this._toggleSpecialsMenu = this._toggleSpecialsMenu.bind(this);
this._rollWorst = this._rollWorst.bind(this); this._rollWorst = this._rollWorst.bind(this);
this._rollRandom = this._rollRandom.bind(this); this._rollRandom = this._rollRandom.bind(this);
this._rollAverage = this._rollAverage.bind(this); this._rollAverage = this._rollAverage.bind(this);
@@ -44,13 +45,27 @@ export default class ModificationsMenu extends TranslatedComponent {
*/ */
_initState(props, context) { _initState(props, context) {
let { m, onChange, ship } = props; let { m, onChange, ship } = props;
const { language, tooltip, termtip } = context;
const translate = language.translate;
// Set up the blueprints
let blueprints = []; let blueprints = [];
for (const blueprintName in Modifications.modules[m.grp].blueprints) { for (const blueprintName in Modifications.modules[m.grp].blueprints) {
for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) { for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) {
const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade); const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade);
const key = blueprintName + ':' + 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 modifications = this._setModifications(props);
const blueprintMenuOpened = false; const blueprintMenuOpened = false;
const specialMenuOpened = false;
// Set up the specials for this module return { blueprintMenuOpened, blueprints, modifications, specialMenuOpened, specials };
// const specials = _selectSpecials(m);
return { blueprintMenuOpened, blueprints, modifications };
} }
/** /**
@@ -106,6 +119,34 @@ export default class ModificationsMenu extends TranslatedComponent {
this.props.onChange(); 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 * Provide a 'worst' roll within the information we have
*/ */
@@ -235,13 +276,13 @@ export default class ModificationsMenu extends TranslatedComponent {
* @return {React.Component} List * @return {React.Component} List
*/ */
render() { render() {
const language = this.context.language; const { language, tooltip, termtip } = this.context;
const translate = language.translate; const translate = language.translate;
const { tooltip, termtip } = this.context;
const { m } = this.props; const { m } = this.props;
const { blueprintMenuOpened } = this.state; const { blueprintMenuOpened, specialMenuOpened } = this.state;
const _toggleBlueprintsMenu = this._toggleBlueprintsMenu; const _toggleBlueprintsMenu = this._toggleBlueprintsMenu;
const _toggleSpecialsMenu = this._toggleSpecialsMenu;
const _rollBest = this._rollBest; const _rollBest = this._rollBest;
const _rollWorst = this._rollWorst; const _rollWorst = this._rollWorst;
const _rollAverage = this._rollAverage; const _rollAverage = this._rollAverage;
@@ -257,31 +298,47 @@ export default class ModificationsMenu extends TranslatedComponent {
blueprintLabel = translate('PHRASE_SELECT_BLUEPRINT'); 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 ( return (
<div <div
className={cn('select', this.props.className)} className={cn('select', this.props.className)}
onClick={(e) => e.stopPropagation() } onClick={(e) => e.stopPropagation() }
onContextMenu={stopCtxPropagation} onContextMenu={stopCtxPropagation}
> >
<div className={ cn('section-menu', { selected: true })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div> <div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
{ blueprintMenuOpened ? this.state.blueprints : '' } { showBlueprintsMenu ? this.state.blueprints : '' }
{ haveBlueprint ? { showSpecial ? <div className={ cn('section-menu', { selected: specialMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleSpecialsMenu}>{specialLabel}</div> : '' }
<table style={{ width: '100%', backgroundColor: 'transparent' }}> { showSpecialsMenu ? this.state.specials : '' }
<tbody> { showRolls ?
<tr> <table style={{ width: '100%', backgroundColor: 'transparent' }}>
<td> { translate('roll') }: </td> <tbody>
<td style={{ cursor: 'pointer' }} onClick={_rollWorst} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('worst') } </td> <tr>
<td style={{ cursor: 'pointer' }} onClick={_rollAverage}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_AVERAGE')} onMouseOut={tooltip.bind(null, null)}> { translate('average') } </td> <td> { translate('roll') }: </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={_rollWorst} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('worst') } </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={_rollAverage}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_AVERAGE')} onMouseOut={tooltip.bind(null, null)}> { translate('average') } </td>
<td style={{ cursor: 'pointer' }} onClick={_reset}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RESET')} onMouseOut={tooltip.bind(null, null)}> { translate('reset') } </td> <td style={{ cursor: 'pointer' }} onClick={_rollBest}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('best') } </td>
</tr> <td style={{ cursor: 'pointer' }} onClick={_rollRandom} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RANDOM')} onMouseOut={tooltip.bind(null, null)}> { translate('random') } </td>
</tbody> <td style={{ cursor: 'pointer' }} onClick={_reset}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RESET')} onMouseOut={tooltip.bind(null, null)}> { translate('reset') } </td>
</tr>
</tbody>
</table> : '' } </table> : '' }
{ blueprintMenuOpened ? '' : { showMods ?
<span onMouseOver={termtip.bind(null, 'HELP_MODIFICATIONS_MENU')} onMouseOut={tooltip.bind(null, null)} > <span onMouseOver={termtip.bind(null, 'HELP_MODIFICATIONS_MENU')} onMouseOut={tooltip.bind(null, null)} >
{ this.state.modifications } { this.state.modifications }
</span> } </span> : '' }
</div> </div>
); );
} }

View File

@@ -91,7 +91,8 @@ export default class StandardSlot extends TranslatedComponent {
<div className={'r'}>{formats.round(mass)}{units.T}</div> <div className={'r'}>{formats.round(mass)}{units.T}</div>
<div/> <div/>
<div className={'cb'}> <div className={'cb'}>
{ m.getOptimalMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptimalMass())}{units.T}</div> : null } { m.getMinMass() ? <div className='l'>{translate('minimum mass')}: {formats.int(m.getMinMass())}{units.T}</div> : null }
{ m.getOptMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptMass())}{units.T}</div> : null }
{ m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null } { m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null }
{ m.getRange() ? <div className='l'>{translate('range')}: {formats.f2(m.getRange())}{units.km}</div> : null } { m.getRange() ? <div className='l'>{translate('range')}: {formats.f2(m.getRange())}{units.km}</div> : null }
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null } { m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }

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_RANDOM: 'Random selection between worst and best primary values for this blueprint',
PHRASE_BLUEPRINT_BEST: 'Best primary values for this blueprint', PHRASE_BLUEPRINT_BEST: 'Best primary values for this blueprint',
PHRASE_BLUEPRINT_RESET: 'Remove all modifications and 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', HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes',
@@ -289,7 +291,7 @@ The damage received panel provides information about the effectiveness of your b
<dt>Ctrl-e</dt><dd>open export dialogue (outfitting page only)</dd> <dt>Ctrl-e</dt><dd>open export dialogue (outfitting page only)</dd>
<dt>Ctrl-h</dt><dd>open help dialogue</dd> <dt>Ctrl-h</dt><dd>open help dialogue</dd>
<dt>Ctrl-i</dt><dd>open import dialogue</dd> <dt>Ctrl-i</dt><dd>open import dialogue</dd>
<dt>Ctrl-l</dt><dd>open shortlink dialogue</dd> <dt>Ctrl-o</dt><dd>open shortlink dialogue</dd>
<dt>Esc</dt><dd>close any open dialogue</dd> <dt>Esc</dt><dd>close any open dialogue</dd>
</dl> </dl>
<h1>Glossary</h1> <h1>Glossary</h1>

View File

@@ -251,7 +251,6 @@ export default class ShipyardPage extends Page {
return ( return (
<div className='page' style={{ fontSize: sizeRatio + 'em' }}> <div className='page' style={{ fontSize: sizeRatio + 'em' }}>
<p style={{ textAlign: 'center' }}>This is <strong>Coriolis EDCD Edition</strong> - a temporary clone of <a href='https://coriolis.io/' target='_blank'>https://coriolis.io/</a> with added support for E:D 2.2. For more info see Settings / <Link href="/about" className='block'>About</Link></p>
<div style={{ whiteSpace: 'nowrap', margin: '0 auto', fontSize: '0.8em', position: 'relative', display: 'inline-block', maxWidth: '100%' }}> <div style={{ whiteSpace: 'nowrap', margin: '0 auto', fontSize: '0.8em', position: 'relative', display: 'inline-block', maxWidth: '100%' }}>
<table style={{ width: '12em', position: 'absolute', zIndex: 1 }}> <table style={{ width: '12em', position: 'absolute', zIndex: 1 }}>
<thead> <thead>

View File

@@ -10,7 +10,7 @@ import Module from './Module';
*/ */
export function jumpRange(mass, fsd, fuel) { export function jumpRange(mass, fsd, fuel) {
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel; let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptimalMass() : fsd.optmass; let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass; return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass;
} }
@@ -24,7 +24,7 @@ export function jumpRange(mass, fsd, fuel) {
*/ */
export function fastestRange(mass, fsd, fuel) { export function fastestRange(mass, fsd, fuel) {
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel; let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptimalMass() : fsd.optmass; let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
let fuelRemaining = fuel % fsdMaxFuelPerJump; // Fuel left after making N max jumps let fuelRemaining = fuel % fsdMaxFuelPerJump; // Fuel left after making N max jumps
let jumps = Math.floor(fuel / fsdMaxFuelPerJump); let jumps = Math.floor(fuel / fsdMaxFuelPerJump);
mass += fuelRemaining; mass += fuelRemaining;

View File

@@ -36,75 +36,126 @@ export default class Module {
/** /**
* Get a value for a given modification * Get a value for a given modification
* @param {Number} name The name of the 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} 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) { getModValue(name, raw) {
return this.mods && this.mods[name] ? this.mods[name] : null; 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 * 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 {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) { if (!this.mods) {
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) { if (value == null || value == 0) {
delete this.mods[name]; delete this.mods[name];
} else { } else {
if (isNaN(value)) { this.mods[name] = value;
this.mods[name] = value;
} else {
// Round just to be sure
this.mods[name] = Math.round(value);
}
} }
} }
/** /**
* Helper to obtain a modified value using standard multipliers * Helper to obtain a modified value using standard multipliers
* @param {String} name the name of the modifier to obtain * @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 * @return {Number} the mass of this module
*/ */
_getModifiedValue(name, additive) { _getModifiedValue(name) {
let result = this[name] || (additive ? 0 : null); // Additive NULL === 0 const modification = Modifications.modifications[name];
if (result != null) { let result = this[name];
const modification = Modifications.modifications[name];
if (!modification) {
return result;
}
// We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise if (!result) {
// we divide by 100. Both ways we end up with a value with two decimal places if (modification && modification.method === 'additive') {
let modValue; // Additive modifications start at 0 rather than NULL
if (modification.type === 'percentage') { result = 0;
modValue = this.getModValue(name) / 10000;
} else if (modification.type === 'numeric') {
modValue = this.getModValue(name) / 100;
} else { } 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 { } 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 { } else {
if (name === 'burst') { if (name === 'burst') {
// Burst is special, as if it can not exist but have a modification // Burst is special, as if it can not exist but have a modification
const modValue = this.getModValue(name) / 100; result = this.getModValue(name) / 100;
return modValue;
} else if (name === 'burstrof') { } else if (name === 'burstrof') {
// Burst rate of fire is special, as if it can not exist but have a modification // Burst rate of fire is special, as if it can not exist but have a modification
const modValue = this.getModValue(name) / 100; result = this.getModValue(name) / 100;
return modValue;
} }
} }
@@ -159,30 +210,6 @@ export default class Module {
return this._getModifiedValue('eff'); return this._getModifiedValue('eff');
} }
/**
* Get the maximum mass of this module, taking in to account modifications
* @return {Number} the maximum mass of this module
*/
getMaxMass() {
return this._getModifiedValue('maxmass');
}
/**
* Get the optimal mass of this module, taking in to account modifications
* @return {Number} the optimal mass of this module
*/
getOptimalMass() {
return this._getModifiedValue('optmass');
}
/**
* Get the optimal multiplier of this module, taking in to account modifications
* @return {Number} the optimal multiplier of this module
*/
getOptimalMultiplier() {
return this._getModifiedValue('optmult');
}
/** /**
* Get the maximum fuel per jump for this module, taking in to account modifications * Get the maximum fuel per jump for this module, taking in to account modifications
* @return {Number} the maximum fuel per jump of this module * @return {Number} the maximum fuel per jump of this module
@@ -244,7 +271,7 @@ export default class Module {
* @return {Number} the kinetic resistance of this module * @return {Number} the kinetic resistance of this module
*/ */
getKineticResistance() { getKineticResistance() {
return this._getModifiedValue('kinres', true); return this._getModifiedValue('kinres');
} }
/** /**
@@ -252,7 +279,7 @@ export default class Module {
* @return {Number} the thermal resistance of this module * @return {Number} the thermal resistance of this module
*/ */
getThermalResistance() { getThermalResistance() {
return this._getModifiedValue('thermres', true); return this._getModifiedValue('thermres');
} }
/** /**
@@ -260,7 +287,7 @@ export default class Module {
* @return {Number} the explosive resistance of this module * @return {Number} the explosive resistance of this module
*/ */
getExplosiveResistance() { getExplosiveResistance() {
return this._getModifiedValue('explres', true); return this._getModifiedValue('explres');
} }
/** /**
@@ -671,9 +698,25 @@ export default class Module {
/** /**
* Get the shot speed for this module, taking in to account modifications * 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() { getShotSpeed() {
return this._getModifiedValue('shotspeed'); 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

@@ -90,7 +90,7 @@ export function toDetailedBuild(buildName, ship) {
code = ship.toString(); code = ship.toString();
let data = { let data = {
$schema: 'http://cdn.coriolis.io/schemas/ship-loadout/4.json#', $schema: 'https://coriolis.edcd.io/schemas/ship-loadout/4.json#',
name: buildName, name: buildName,
ship: ship.name, ship: ship.name,
references: [{ references: [{

View File

@@ -438,12 +438,13 @@ export default class Ship {
} }
/** /**
* Set a modification value * Set a modification value and update ship stats
* @param {Object} m The module to change * @param {Object} m The module to change
* @param {Object} name The name of the modification 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 {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)) { if (isNaN(value)) {
// Value passed is invalid; reset it to 0 // Value passed is invalid; reset it to 0
value = 0; value = 0;
@@ -452,58 +453,58 @@ export default class Ship {
// Handle special cases // Handle special cases
if (name === 'pgen') { if (name === 'pgen') {
// Power generation // Power generation
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.updatePowerGenerated(); this.updatePowerGenerated();
} else if (name === 'power') { } else if (name === 'power') {
// Power usage // Power usage
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.updatePowerUsed(); this.updatePowerUsed();
} else if (name === 'mass') { } else if (name === 'mass') {
// Mass // Mass
let oldMass = m.getMass(); let oldMass = m.getMass();
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
let newMass = m.getMass(); let newMass = m.getMass();
this.unladenMass = this.unladenMass - oldMass + newMass; this.unladenMass = this.unladenMass - oldMass + newMass;
this.ladenMass = this.ladenMass - oldMass + newMass; this.ladenMass = this.ladenMass - oldMass + newMass;
this.updateMovement(); this.updateMovement();
this.updateJumpStats(); this.updateJumpStats();
} else if (name === 'maxfuel') { } else if (name === 'maxfuel') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.updateJumpStats(); this.updateJumpStats();
} else if (name === 'optmass') { } else if (name === 'optmass') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
// Could be for any of thrusters, FSD or shield // Could be for any of thrusters, FSD or shield
this.updateMovement(); this.updateMovement();
this.updateJumpStats(); this.updateJumpStats();
this.recalculateShield(); this.recalculateShield();
} else if (name === 'optmul') { } else if (name === 'optmul') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
// Could be for any of thrusters, FSD or shield // Could be for any of thrusters, FSD or shield
this.updateMovement(); this.updateMovement();
this.updateJumpStats(); this.updateJumpStats();
this.recalculateShield(); this.recalculateShield();
} else if (name === 'shieldboost') { } else if (name === 'shieldboost') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.recalculateShield(); this.recalculateShield();
} else if (name === 'hullboost' || name === 'hullreinforcement' || name === 'modulereinforcement') { } else if (name === 'hullboost' || name === 'hullreinforcement' || name === 'modulereinforcement') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.recalculateArmour(); this.recalculateArmour();
} else if (name === 'shieldreinforcement') { } else if (name === 'shieldreinforcement') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
this.recalculateShieldCells(); 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') { } 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.recalculateDps();
this.recalculateHps(); this.recalculateHps();
this.recalculateEps(); this.recalculateEps();
} else if (name === 'explres' || name === 'kinres' || name === 'thermres') { } else if (name === 'explres' || name === 'kinres' || name === 'thermres') {
m.setModValue(name, value); m.setModValue(name, value, sentfromui);
// Could be for shields or armour // Could be for shields or armour
this.recalculateArmour(); this.recalculateArmour();
this.recalculateShield(); this.recalculateShield();
} else { } else {
// Generic // 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) { for (let modKey in this.bulkheads.m.mods) {
// Filter out invalid modifications // Filter out invalid modifications
if (Modifications.modules['bh'] && Modifications.modules['bh'].modifications.indexOf(modKey) != -1) { 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; bulkheadBlueprint = this.bulkheads.m.blueprint;
@@ -1391,7 +1392,7 @@ export default class Ship {
for (let modKey in slot.m.mods) { for (let modKey in slot.m.mods) {
// Filter out invalid modifications // Filter out invalid modifications
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { 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) { for (let modKey in slot.m.mods) {
// Filter out invalid modifications // Filter out invalid modifications
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { 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) { for (let modKey in slot.m.mods) {
// Filter out invalid modifications // Filter out invalid modifications
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) { 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') { } else if (modifiers.modifiers[i].name === 'mod_weapon_falloffrange_from_range') {
// Obtain the falloff value directly from the range // Obtain the falloff value directly from the range
module.setModValue('fallofffromrange', 1); 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 { } else {
// Look up the modifiers to find what we need to do // Look up the modifiers to find what we need to do
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name]; 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 // Add the blueprint ID, grade and special

View File

@@ -151,13 +151,15 @@ export function diffDetails(language, m, mm) {
let mmMass = mm ? mm.getMass() : 0; let mmMass = mm ? mm.getMass() : 0;
if (mMass != mmMass) propDiffs.push(<div key='mass'>{translate('mass')}: <span className={diffClass(mMass, mmMass, true)}>{diff(formats.round, mMass, mmMass)}{units.T}</span></div>); if (mMass != mmMass) propDiffs.push(<div key='mass'>{translate('mass')}: <span className={diffClass(mMass, mmMass, true)}>{diff(formats.round, mMass, mmMass)}{units.T}</span></div>);
let mPowerGeneration = m.pgen || 0; if (m.grp === 'pp') {
let mmPowerGeneration = mm ? mm.getPowerGeneration() : 0; let mPowerGeneration = m.pgen || 0;
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MJ}</span></div>); let mmPowerGeneration = mm ? mm.getPowerGeneration() : 0;
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MJ}</span></div>);
let mPowerUsage = m.power || 0; } else {
let mmPowerUsage = mm ? mm.getPowerUsage() : 0; let mPowerUsage = m.power || 0;
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MJ}</span></div>); let mmPowerUsage = mm ? mm.getPowerUsage() : 0;
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MJ}</span></div>);
}
let mDps = m.damage * (m.rpshot || 1) * (m.rof || 1) || 0; let mDps = m.damage * (m.rpshot || 1) * (m.rof || 1) || 0;
let mmDps = mm ? mm.getDps() || 0 : 0; let mmDps = mm ? mm.getDps() || 0 : 0;

View File

@@ -1,5 +1,5 @@
{ {
"name": "Coriolis.io", "name": "Coriolis EDCD Edition",
"short_name": "Coriolis", "short_name": "Coriolis",
"icons": [ "icons": [
{ {
@@ -27,7 +27,7 @@
"density": "4.0" "density": "4.0"
} }
], ],
"start_url": "http:\/\/coriolis.io", "start_url": "https:\/\/edcd.coriolis.io",
"display": "standalone", "display": "standalone",
"orientation": "portrait" "orientation": "portrait"
} }

View File

@@ -1,6 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", "id": "https://coriolis.edcd.io/schemas/ship-loadout/1.json#",
"title": "Ship Loadout", "title": "Ship Loadout",
"type": "object", "type": "object",
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3", "description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
@@ -278,4 +278,4 @@
"standardRatings": { "enum": ["A", "B", "C", "D", "E"] }, "standardRatings": { "enum": ["A", "B", "C", "D", "E"] },
"allRatings": { "enum": ["A", "B", "C", "D", "E", "F", "I" ] } "allRatings": { "enum": ["A", "B", "C", "D", "E", "F", "I" ] }
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://cdn.coriolis.io/schemas/ship-loadout/2.json#", "id": "https://coriolis.edcd.io/schemas/ship-loadout/2.json#",
"title": "Ship Loadout", "title": "Ship Loadout",
"type": "object", "type": "object",
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3", "description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",

View File

@@ -1,6 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://cdn.coriolis.io/schemas/ship-loadout/3.json#", "id": "https://coriolis.edcd.io/schemas/ship-loadout/3.json#",
"title": "Ship Loadout", "title": "Ship Loadout",
"type": "object", "type": "object",
"description": "The details for a specific ship build/loadout", "description": "The details for a specific ship build/loadout",

View File

@@ -1,6 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://cdn.coriolis.io/schemas/ship-loadout/4.json#", "id": "https://coriolis.edcd.io/schemas/ship-loadout/4.json#",
"title": "Ship Loadout", "title": "Ship Loadout",
"type": "object", "type": "object",
"description": "The details for a specific ship build/loadout", "description": "The details for a specific ship build/loadout",