mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 14:33:22 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca0c9675b3 | ||
|
|
491899fe49 | ||
|
|
cc22a89ad6 | ||
|
|
d389114189 | ||
|
|
9d0f7a166b | ||
|
|
c344d56d48 | ||
|
|
eb5d0e868c | ||
|
|
c28f22a78b | ||
|
|
e2b22dd4ca | ||
|
|
f5ecccec48 | ||
|
|
7c8eee4707 | ||
|
|
99e251fd4b | ||
|
|
c1ddecfd3e | ||
|
|
0ae59c5e48 | ||
|
|
eb76040b08 | ||
|
|
7698cb75e9 | ||
|
|
bd7139c703 | ||
|
|
c9b9404ba1 | ||
|
|
84ff013a9e | ||
|
|
d2bcf6cd71 | ||
|
|
e52c6730f4 | ||
|
|
e448b3cb0a | ||
|
|
705f3158aa | ||
|
|
f4789717fe | ||
|
|
93e69f215b | ||
|
|
d04e662de4 | ||
|
|
db376829f5 | ||
|
|
79a31fd992 | ||
|
|
094f3aa3e2 | ||
|
|
41d51743d3 | ||
|
|
cf741d18ed |
10
ChangeLog.md
10
ChangeLog.md
@@ -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
|
||||
* Add help system and initial help file
|
||||
* Make absolute damage visible
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "coriolis_shipyard",
|
||||
"version": "2.2.11",
|
||||
"version": "2.2.12",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EDCD/coriolis"
|
||||
|
||||
@@ -174,11 +174,12 @@ export default class Coriolis extends React.Component {
|
||||
this._showModal(<ModalImport />);
|
||||
}
|
||||
break;
|
||||
case 76: // 'l'
|
||||
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + l
|
||||
case 79: // 'o'
|
||||
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + o
|
||||
e.preventDefault();
|
||||
this._showModal(<ModalPermalink url={window.location.href}/>);
|
||||
}
|
||||
break;
|
||||
case 83: // 's'
|
||||
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + s
|
||||
e.preventDefault();
|
||||
|
||||
@@ -103,6 +103,8 @@ export default class DamageDealt extends TranslatedComponent {
|
||||
* @return {boolean} Returns the per-weapon damage
|
||||
*/
|
||||
_calcWeapons(ship, against, range) {
|
||||
const translate = this.context.language.translate;
|
||||
|
||||
// Tidy up the range so that it's to 4 decimal places
|
||||
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 : ''}`;
|
||||
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 effectiveDpsShields = m.getDps() * effectivenessShields;
|
||||
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,
|
||||
name: m.name || m.grp,
|
||||
classRating,
|
||||
engineering,
|
||||
effectiveDpsShields,
|
||||
effectiveSDpsShields,
|
||||
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;
|
||||
console.log('total effective dps shields is ' + totals.effectiveDpsShields);
|
||||
totals.effectivenessHull = totalDps == 0 ? 0 : totals.effectiveDpsHull / totalDps;
|
||||
|
||||
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 == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
|
||||
{weapon.classRating} {translate(weapon.name)}
|
||||
{weapon.engineering ? ' (' + weapon.engineering + ')' : null }
|
||||
</td>
|
||||
<td className='ri'>{formats.round1(weapon.effectiveDpsShields)}</td>
|
||||
<td className='ri'>{formats.round1(weapon.effectiveSDpsShields)}</td>
|
||||
|
||||
@@ -47,13 +47,13 @@ export default class InternalSlot extends Slot {
|
||||
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {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> {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> {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.time(m.getTime())}</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 }
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
||||
<div/>
|
||||
<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.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 }
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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-h</dt><dd>open help 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>
|
||||
</dl>
|
||||
<h1>Glossary</h1>
|
||||
|
||||
@@ -251,7 +251,6 @@ export default class ShipyardPage extends Page {
|
||||
|
||||
return (
|
||||
<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%' }}>
|
||||
<table style={{ width: '12em', position: 'absolute', zIndex: 1 }}>
|
||||
<thead>
|
||||
|
||||
@@ -10,7 +10,7 @@ import Module from './Module';
|
||||
*/
|
||||
export function jumpRange(mass, fsd, fuel) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function jumpRange(mass, fsd, fuel) {
|
||||
*/
|
||||
export function fastestRange(mass, fsd, fuel) {
|
||||
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 jumps = Math.floor(fuel / fsdMaxFuelPerJump);
|
||||
mass += fuelRemaining;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,30 +210,6 @@ export default class Module {
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
* @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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ export function toDetailedBuild(buildName, ship) {
|
||||
code = ship.toString();
|
||||
|
||||
let data = {
|
||||
$schema: 'http://cdn.coriolis.io/schemas/ship-loadout/4.json#',
|
||||
$schema: 'https://coriolis.edcd.io/schemas/ship-loadout/4.json#',
|
||||
name: buildName,
|
||||
ship: ship.name,
|
||||
references: [{
|
||||
|
||||
@@ -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) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -151,13 +151,15 @@ export function diffDetails(language, m, mm) {
|
||||
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>);
|
||||
|
||||
let mPowerGeneration = m.pgen || 0;
|
||||
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;
|
||||
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>);
|
||||
if (m.grp === 'pp') {
|
||||
let mPowerGeneration = m.pgen || 0;
|
||||
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>);
|
||||
} else {
|
||||
let mPowerUsage = m.power || 0;
|
||||
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 mmDps = mm ? mm.getDps() || 0 : 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Coriolis.io",
|
||||
"name": "Coriolis EDCD Edition",
|
||||
"short_name": "Coriolis",
|
||||
"icons": [
|
||||
{
|
||||
@@ -27,7 +27,7 @@
|
||||
"density": "4.0"
|
||||
}
|
||||
],
|
||||
"start_url": "http:\/\/coriolis.io",
|
||||
"start_url": "https:\/\/edcd.coriolis.io",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$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",
|
||||
"type": "object",
|
||||
"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"] },
|
||||
"allRatings": { "enum": ["A", "B", "C", "D", "E", "F", "I" ] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$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",
|
||||
"type": "object",
|
||||
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$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",
|
||||
"type": "object",
|
||||
"description": "The details for a specific ship build/loadout",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$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",
|
||||
"type": "object",
|
||||
"description": "The details for a specific ship build/loadout",
|
||||
|
||||
Reference in New Issue
Block a user