mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 06:43:24 +00:00
Merge branch 'release/2.2.0'
This commit is contained in:
@@ -108,7 +108,8 @@ describe('Import Modal', function() {
|
|||||||
it('catches an invalid backup', function() {
|
it('catches an invalid backup', function() {
|
||||||
const importData = require('./fixtures/valid-backup');
|
const importData = require('./fixtures/valid-backup');
|
||||||
let invalidImportData = Object.assign({}, importData);
|
let invalidImportData = Object.assign({}, importData);
|
||||||
invalidImportData.builds.asp = null; // Remove Asp Miner build used in comparison
|
//invalidImportData.builds.asp = null; // Remove Asp Miner build used in comparison
|
||||||
|
delete(invalidImportData.builds.asp);
|
||||||
|
|
||||||
pasteText('"this is not valid"');
|
pasteText('"this is not valid"');
|
||||||
expect(modal.state.importValid).toBeFalsy();
|
expect(modal.state.importValid).toBeFalsy();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe("Ship", function() {
|
|||||||
ship.buildWith(shipData.defaults);
|
ship.buildWith(shipData.defaults);
|
||||||
|
|
||||||
expect(ship.totalCost).toEqual(shipData.retailCost, s + ' retail cost does not match default build cost');
|
expect(ship.totalCost).toEqual(shipData.retailCost, s + ' retail cost does not match default build cost');
|
||||||
expect(ship.cargoCapacity).toBeDefined(s + ' cargo');
|
expect(ship.cargoCapacity).toBeDefined();
|
||||||
expect(ship.priorityBands[0].retracted).toBeGreaterThan(0, s + ' priorityBands');
|
expect(ship.priorityBands[0].retracted).toBeGreaterThan(0, s + ' priorityBands');
|
||||||
expect(ship.powerAvailable).toBeGreaterThan(0, s + ' powerAvailable');
|
expect(ship.powerAvailable).toBeGreaterThan(0, s + ' powerAvailable');
|
||||||
expect(ship.unladenRange).toBeGreaterThan(0, s + ' unladenRange');
|
expect(ship.unladenRange).toBeGreaterThan(0, s + ' unladenRange');
|
||||||
|
|||||||
15
package.json
15
package.json
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "coriolis_shipyard",
|
"name": "coriolis_shipyard",
|
||||||
"version": "2.1.2",
|
"version": "2.2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/cmmcleod/coriolis"
|
"url": "https://github.com/EDCD/coriolis"
|
||||||
},
|
},
|
||||||
"homepage": "https://coriolis.io",
|
"homepage": "https://coriolis.edcd.io",
|
||||||
"bugs": "https://github.com/cmmcleod/coriolis/issues",
|
"bugs": "https://github.com/EDCD/coriolis/issues",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engine": "node >= 4.0.0",
|
"engine": "node >= 4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -24,14 +24,13 @@
|
|||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
|
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
|
||||||
"testFileExtensions": [
|
"testRegex": "(/__tests__/test-.*|\\.(test|spec))\\.js$",
|
||||||
"js"
|
|
||||||
],
|
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
"js",
|
"js",
|
||||||
"json",
|
"json",
|
||||||
"jsx"
|
"jsx"
|
||||||
],
|
],
|
||||||
|
"automock": true,
|
||||||
"unmockedModulePathPatterns": [
|
"unmockedModulePathPatterns": [
|
||||||
"<rootDir>/node_modules/react",
|
"<rootDir>/node_modules/react",
|
||||||
"<rootDir>/node_modules/react-dom",
|
"<rootDir>/node_modules/react-dom",
|
||||||
@@ -68,7 +67,7 @@
|
|||||||
"extract-text-webpack-plugin": "^0.9.1",
|
"extract-text-webpack-plugin": "^0.9.1",
|
||||||
"file-loader": "^0.8.4",
|
"file-loader": "^0.8.4",
|
||||||
"html-webpack-plugin": "^1.7.0",
|
"html-webpack-plugin": "^1.7.0",
|
||||||
"jest-cli": "^0.9.2",
|
"jest-cli": "^16.0.1",
|
||||||
"jsen": "^0.6.0",
|
"jsen": "^0.6.0",
|
||||||
"json-loader": "^0.5.3",
|
"json-loader": "^0.5.3",
|
||||||
"less": "^2.5.3",
|
"less": "^2.5.3",
|
||||||
|
|||||||
@@ -606,6 +606,7 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nextProps.ship != this.props.ship || nextProps.code != this.props.code) {
|
if (nextProps.ship != this.props.ship || nextProps.code != this.props.code) {
|
||||||
|
nextProps.ship.applyDiscounts(Persist.getShipDiscount(), Persist.getModuleDiscount());
|
||||||
this._updateAmmoCosts(nextProps.ship);
|
this._updateAmmoCosts(nextProps.ship);
|
||||||
this._updateRetrofit(nextProps.ship, retrofitShip);
|
this._updateRetrofit(nextProps.ship, retrofitShip);
|
||||||
this._sortCost(nextProps.ship);
|
this._sortCost(nextProps.ship);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Slot from './Slot';
|
import Slot from './Slot';
|
||||||
|
import { DamageKinetic, DamageThermal, DamageExplosive, MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hardpoint / Utility Slot
|
* Hardpoint / Utility Slot
|
||||||
@@ -33,24 +34,31 @@ export default class HardpointSlot extends Slot {
|
|||||||
*/
|
*/
|
||||||
_getSlotDetails(m, translate, formats, u) {
|
_getSlotDetails(m, translate, formats, u) {
|
||||||
if (m) {
|
if (m) {
|
||||||
let classRating = `${m.class}${m.rating}${m.mount ? '/' + m.mount : ''}${m.missile ? m.missile : ''}`;
|
let classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
||||||
let { drag, drop } = this.props;
|
let { drag, drop } = this.props;
|
||||||
|
|
||||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}</div>
|
<div className={'l'}>
|
||||||
|
{m.mount && m.mount == 'F' ? <MountFixed /> : ''}
|
||||||
|
{m.mount && m.mount == 'G' ? <MountGimballed /> : ''}
|
||||||
|
{m.mount && m.mount == 'T' ? <MountTurret /> : ''}
|
||||||
|
{m.type && m.type == 'K' ? <DamageKinetic /> : ''}
|
||||||
|
{m.type && m.type == 'T' ? <DamageThermal /> : ''}
|
||||||
|
{m.type && m.type == 'KT' ? <span><DamageKinetic /><DamageThermal /></span> : ''}
|
||||||
|
{m.type && m.type == 'E' ? <DamageExplosive /> : ''}
|
||||||
|
{classRating} {translate(m.name || m.grp)}</div>
|
||||||
<div className={'r'}>{m.mass}{u.T}</div>
|
<div className={'r'}>{m.mass}{u.T}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{ m.damage ? <div className={'l'}>{translate('damage')}: {m.damage} { m.ssdam ? <span>({formats.int(m.ssdam)} {u.MJ})</span> : null }</div> : null }
|
{ m.dps ? <div className={'l'}>{translate('DPS')}: {formats.round1(m.dps)} { m.clip ? <span>({formats.round1((m.clip * m.dps / m.rof) / ((m.clip / m.rof) + m.reload)) })</span> : null }</div> : null }
|
||||||
{ m.dps ? <div className={'l'}>{translate('DPS')}: {m.dps} { m.mjdps ? <span>({formats.int(m.mjdps)} {u.MJ})</span> : null }</div> : null }
|
{ m.eps ? <div className={'l'}>{translate('EPS')}: {formats.round1(m.eps)} { m.clip ? <span>({formats.round1((m.clip * m.eps / m.rof) / ((m.clip / m.rof) + m.reload)) })</span> : null }</div> : null }
|
||||||
{ m.thermload ? <div className={'l'}>{translate('T-Load')}: {m.thermload}</div> : null }
|
{ m.hps ? <div className={'l'}>{translate('HPS')}: {formats.round1(m.hps)} { m.clip ? <span>({formats.round1((m.clip * m.hps / m.rof) / ((m.clip / m.rof) + m.reload)) })</span> : null }</div> : null }
|
||||||
{ m.type ? <div className={'l'}>{translate('type')}: {m.type}</div> : null }
|
{ m.dps && m.eps ? <div className={'l'}>{translate('DPE')}: {formats.round1(m.dps / m.eps)}</div> : null }
|
||||||
{ m.rof ? <div className={'l'}>{translate('ROF')}: {m.rof}{u.ps}</div> : null }
|
{ m.rof ? <div className={'l'}>{translate('ROF')}: {m.rof}{u.ps}</div> : null }
|
||||||
{ m.armourpen ? <div className={'l'}>{translate('pen')}: {m.armourpen}</div> : null }
|
{ m.range && !m.dps ? <div className={'l'}>{translate('Range')} : {formats.round(m.range / 1000)}{u.km}</div> : null }
|
||||||
{ m.shieldmul ? <div className={'l'}>+{formats.rPct(m.shieldmul)}</div> : null }
|
{ m.shieldmul ? <div className={'l'}>+{formats.rPct(m.shieldmul)}</div> : null }
|
||||||
{ m.range ? <div className={'l'}>{m.range} <u>km</u></div> : null }
|
{ m.ammo >= 0 ? <div className={'l'}>{translate('ammo')}: {formats.int(m.clip)}/{formats.int(m.ammo)}</div> : null }
|
||||||
{ m.ammo >= 0 ? <div className={'l'}>{translate('ammo')}: {formats.int(m.clip)}+{formats.int(m.ammo)}</div> : null }
|
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export default class InternalSlot extends Slot {
|
|||||||
{ 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 }
|
||||||
{ 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'}><Infinite/>{u.Ls}</div> : null }
|
{ m.rangeLS === null ? <div className={'l'}>∞{u.Ls}</div> : null }
|
||||||
{ m.rangeRating ? <div className={'l'}>{translate('range')}: {m.rangeRating}</div> : null }
|
{ m.rangeRating ? <div className={'l'}>{translate('range')}: {m.rangeRating}</div> : null }
|
||||||
{ m.armouradd ? <div className={'l'}>+{m.armouradd} <u className='cap'>{translate('armour')}</u></div> : null }
|
{ m.armouradd ? <div className={'l'}>+{m.armouradd} <u className='cap'>{translate('armour')}</u></div> : null }
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default class InternalSlotSection extends SlotSection {
|
|||||||
let ship = this.props.ship;
|
let ship = this.props.ship;
|
||||||
let chargeCap = 0; // Capacity of single activation
|
let chargeCap = 0; // Capacity of single activation
|
||||||
ship.internal.forEach(function(slot) {
|
ship.internal.forEach(function(slot) {
|
||||||
if ((!slot.m || (clobber && !ModuleUtils.isShieldGenerator(slot.m.grp))) && (!slot.eligible || slot.eligible.scb)) { // Check eligibility due to Orca special case
|
if ((!slot.m || (clobber && !ModuleUtils.isShieldGenerator(slot.m.grp))) && (!slot.eligible || slot.eligible.scb)) { // Check eligibility due to passenger ships special case
|
||||||
ship.use(slot, ModuleUtils.findInternal('scb', slot.maxClass, 'A'));
|
ship.use(slot, ModuleUtils.findInternal('scb', slot.maxClass, 'A'));
|
||||||
ship.setSlotEnabled(slot, chargeCap <= ship.shieldStrength); // Don't waste cell capacity on overcharge
|
ship.setSlotEnabled(slot, chargeCap <= ship.shieldStrength); // Don't waste cell capacity on overcharge
|
||||||
chargeCap += slot.m.recharge;
|
chargeCap += slot.m.recharge;
|
||||||
@@ -108,7 +108,7 @@ export default class InternalSlotSection extends SlotSection {
|
|||||||
slots.push(<InternalSlot
|
slots.push(<InternalSlot
|
||||||
key={i}
|
key={i}
|
||||||
maxClass={s.maxClass}
|
maxClass={s.maxClass}
|
||||||
availableModules={() => availableModules.getInts(s.maxClass, s.eligible)}
|
availableModules={() => availableModules.getInts(ship, s.maxClass, s.eligible)}
|
||||||
onOpen={this._openMenu.bind(this,s)}
|
onOpen={this._openMenu.bind(this,s)}
|
||||||
onSelect={this._selectModule.bind(this, s)}
|
onSelect={this._selectModule.bind(this, s)}
|
||||||
selected={currentMenu == s}
|
selected={currentMenu == s}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
import { wrapCtxMenu } from '../utils/UtilityFunctions';
|
import { wrapCtxMenu } from '../utils/UtilityFunctions';
|
||||||
|
import { canMount } from '../utils/SlotFunctions';
|
||||||
import { Equalizer } from '../components/SvgIcons';
|
import { Equalizer } from '../components/SvgIcons';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ export default class SlotSection extends TranslatedComponent {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
let os = this.state.originSlot;
|
let os = this.state.originSlot;
|
||||||
if (os) {
|
if (os) {
|
||||||
e.dataTransfer.dropEffect = os != targetSlot && targetSlot.maxClass >= os.m.class ? 'copyMove' : 'none';
|
e.dataTransfer.dropEffect = os != targetSlot && canMount(this.props.ship, targetSlot, os.m.grp, os.m.class) ? 'copyMove' : 'none';
|
||||||
this.setState({ targetSlot });
|
this.setState({ targetSlot });
|
||||||
} else {
|
} else {
|
||||||
e.dataTransfer.dropEffect = 'none';
|
e.dataTransfer.dropEffect = 'none';
|
||||||
@@ -116,9 +117,9 @@ export default class SlotSection extends TranslatedComponent {
|
|||||||
let { originSlot, targetSlot } = this.state;
|
let { originSlot, targetSlot } = this.state;
|
||||||
let m = originSlot.m;
|
let m = originSlot.m;
|
||||||
|
|
||||||
if (targetSlot && m && targetSlot.maxClass >= m.class) {
|
if (targetSlot && m && canMount(this.props.ship, targetSlot, m.grp, m.class)) {
|
||||||
// Swap modules if possible
|
// Swap modules if possible
|
||||||
if (targetSlot.m && originSlot.maxClass >= targetSlot.m.class) {
|
if (targetSlot.m && canMount(this.props.ship, originSlot, targetSlot.m.grp, targetSlot.m.class)) {
|
||||||
this.props.ship.use(originSlot, targetSlot.m, true);
|
this.props.ship.use(originSlot, targetSlot.m, true);
|
||||||
} else { // Otherwise empty the origin slot
|
} else { // Otherwise empty the origin slot
|
||||||
this.props.ship.use(originSlot, null, true); // Empty but prevent summary update
|
this.props.ship.use(originSlot, null, true); // Empty but prevent summary update
|
||||||
@@ -141,12 +142,12 @@ export default class SlotSection extends TranslatedComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (slot === originSlot) {
|
if (slot === originSlot) {
|
||||||
if (targetSlot && targetSlot.m && originSlot.maxClass < targetSlot.m.class) {
|
if (targetSlot && targetSlot.m && !canMount(this.props.ship, originSlot, targetSlot.m.grp, targetSlot.m.class)) {
|
||||||
return 'dropEmpty'; // Origin slot will be emptied
|
return 'dropEmpty'; // Origin slot will be emptied
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (originSlot.m && slot.maxClass >= originSlot.m.class) { // Eligble drop slot
|
if (originSlot.m && canMount(this.props.ship, slot, originSlot.m.grp, originSlot.m.class)) { // Eligble drop slot
|
||||||
if (slot === targetSlot) {
|
if (slot === targetSlot) {
|
||||||
return 'drop'; // Can drop
|
return 'drop'; // Can drop
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,6 +319,90 @@ export class Warning extends SvgIcon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thermal damage
|
||||||
|
*/
|
||||||
|
export class DamageThermal extends SvgIcon {
|
||||||
|
/**
|
||||||
|
* Overriden view box
|
||||||
|
* @return {String} view box
|
||||||
|
*/
|
||||||
|
viewBox() { return '0 0 200 200'; }
|
||||||
|
/**
|
||||||
|
* Generate the SVG
|
||||||
|
* @return {React.Component} SVG Contents
|
||||||
|
*/
|
||||||
|
svg() {
|
||||||
|
return <g>
|
||||||
|
<ellipse cx='100' cy='100' rx='90' ry='90' fillOpacity='0' />
|
||||||
|
<ellipse cx='100' cy='100' rx='30' ry='30' fillOpacity='1' />
|
||||||
|
<path d='M100 20v80' />
|
||||||
|
</g>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kinetic damage
|
||||||
|
*/
|
||||||
|
export class DamageKinetic extends SvgIcon {
|
||||||
|
/**
|
||||||
|
* Overriden view box
|
||||||
|
* @return {String} view box
|
||||||
|
*/
|
||||||
|
viewBox() { return '0 0 200 200'; }
|
||||||
|
/**
|
||||||
|
* Generate the SVG
|
||||||
|
* @return {React.Component} SVG Contents
|
||||||
|
*/
|
||||||
|
svg() {
|
||||||
|
return <g>
|
||||||
|
<ellipse cx='100' cy='100' rx='90' ry='90' fillOpacity='0' />
|
||||||
|
<ellipse cx='62' cy='67' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='62' cy='101' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='62' cy='135' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='50' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='84' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='118' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='152' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='138' cy='67' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='138' cy='101' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='138' cy='135' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
</g>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explosive damage
|
||||||
|
*/
|
||||||
|
export class DamageExplosive extends SvgIcon {
|
||||||
|
/**
|
||||||
|
* Overriden view box
|
||||||
|
* @return {String} view box
|
||||||
|
*/
|
||||||
|
viewBox() { return '0 0 200 200'; }
|
||||||
|
/**
|
||||||
|
* Generate the SVG
|
||||||
|
* @return {React.Component} SVG Contents
|
||||||
|
*/
|
||||||
|
svg() {
|
||||||
|
return <g>
|
||||||
|
<ellipse cx='100' cy='100' rx='50' ry='50' fillOpacity='0' />
|
||||||
|
<ellipse cx='100' cy='20' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='156.57' cy='36.57' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='180' cy='100' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='156.57' cy='163.43' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='180' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='43.43' cy='163.43' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='20' cy='100' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='43.43' cy='36.57' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='75' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='125' cy='100' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='100' cy='125' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
<ellipse cx='75' cy='100' rx='5' ry='5' fillOpacity='1' />
|
||||||
|
</g>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixed mount hardpoint
|
* Fixed mount hardpoint
|
||||||
*/
|
*/
|
||||||
@@ -334,11 +418,11 @@ export class MountFixed extends SvgIcon {
|
|||||||
*/
|
*/
|
||||||
svg() {
|
svg() {
|
||||||
return <g>
|
return <g>
|
||||||
<circle fillOpacity='0' r='70' cy='100' cx='100' strokeWidth='5' />
|
<circle cx='100' cy='100' r='76' fillOpacity='0' />
|
||||||
<line y2='60' x2='101' y1='0' x1='101' strokeWidth='5' />
|
<path d='M0 100h48' />
|
||||||
<line y2='101' x2='200' y1='101' x1='140' strokeWidth='5' />
|
<path d='M152 100h48' />
|
||||||
<line y2='101' x2='60' y1='101' x1='0' strokeWidth='5' />
|
<path d='M100 0v48' />
|
||||||
<line y2='200' x2='101' y1='140' x1='101' strokeWidth='5' />
|
<path d='M100 152v48' />
|
||||||
</g>;
|
</g>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,8 +442,8 @@ export class MountGimballed extends SvgIcon {
|
|||||||
*/
|
*/
|
||||||
svg() {
|
svg() {
|
||||||
return <g>
|
return <g>
|
||||||
<ellipse ry='25' rx='95' cy='100' cx='100' fillOpacity='0' strokeWidth='5' />
|
<ellipse cx='100' cy='100' rx='90' ry='25' fillOpacity='0' />
|
||||||
<ellipse ry='95' rx='25' cy='100' cx='100' fillOpacity='0' strokeWidth='5' />
|
<ellipse cx='100' cy='100' rx='20' ry='95' fillOpacity='0' />
|
||||||
</g>;
|
</g>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,9 +463,14 @@ export class MountTurret extends SvgIcon {
|
|||||||
*/
|
*/
|
||||||
svg() {
|
svg() {
|
||||||
return <g>
|
return <g>
|
||||||
<line y2='170' x2='162' y1='170' x1='8' strokeWidth='6' />
|
<path d='M40 50 A 40 40 0 0 0 0 90' />
|
||||||
<path d='m13,138l144,0l0,-50l-27,-40l-90,0l-27,40l0,50z' id='svg_12' fillOpacity='0' strokeWidth='6' />
|
<path d='M40 50h40' />
|
||||||
<line y2='91' x2='200' y1='91' x1='159' strokeWidth='6' />
|
<path d='M120 90 A 40 40 0 0 0 80 50' />
|
||||||
|
<path d='M0 90v40' />
|
||||||
|
<path d='M120 90v40' />
|
||||||
|
<path d='M0 120h120' />
|
||||||
|
<path d='M120 90h80' />
|
||||||
|
<path d='M0 160h120' />
|
||||||
</g>;
|
</g>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,14 @@ export function getLanguage(langCode) {
|
|||||||
formats: {
|
formats: {
|
||||||
gen, // General number format (.e.g 1,001,001.1234)
|
gen, // General number format (.e.g 1,001,001.1234)
|
||||||
int: d3Locale.numberFormat(',.0f'), // Fixed to 0 decimal places (.e.g 1,001)
|
int: d3Locale.numberFormat(',.0f'), // Fixed to 0 decimal places (.e.g 1,001)
|
||||||
|
f1: d3Locale.numberFormat(',.1f'), // Fixed to 1 decimal place (.e.g 1,001.1)
|
||||||
f2: d3Locale.numberFormat(',.2f'), // Fixed to 2 decimal places (.e.g 1,001.10)
|
f2: d3Locale.numberFormat(',.2f'), // Fixed to 2 decimal places (.e.g 1,001.10)
|
||||||
s2: d3Locale.numberFormat('.2s'), // SI Format to 2 decimal places (.e.g 1.1k)
|
s2: d3Locale.numberFormat('.2s'), // SI Format to 2 decimal places (.e.g 1.1k)
|
||||||
pct: d3Locale.numberFormat('.2%'), // % to 2 decimal places (.e.g 5.40%)
|
pct: d3Locale.numberFormat('.2%'), // % to 2 decimal places (.e.g 5.40%)
|
||||||
pct1: d3Locale.numberFormat('.1%'), // % to 1 decimal places (.e.g 5.4%)
|
pct1: d3Locale.numberFormat('.1%'), // % to 1 decimal places (.e.g 5.4%)
|
||||||
r2: d3Locale.numberFormat('.2r'), // Rounded to 2 significant numbers (.e.g 512 => 510, 4.122 => 4.1)
|
r2: d3Locale.numberFormat('.2r'), // Rounded to 2 significant numbers (.e.g 512 => 510, 4.122 => 4.1)
|
||||||
rPct: d3.format('%'), // % to 0 decimal places (.e.g 5%)
|
rPct: d3.format('%'), // % to 0 decimal places (.e.g 5%)
|
||||||
|
round1: (d) => gen(d3.round(d, 1)), // Rounded to 0-1 decimal places (.e.g 5.1, 4)
|
||||||
round: (d) => gen(d3.round(d, 2)), // Rounded to 0-2 decimal places (.e.g 5.12, 4.1)
|
round: (d) => gen(d3.round(d, 2)), // Rounded to 0-2 decimal places (.e.g 5.12, 4.1)
|
||||||
time: (d) => (d < 0 ? '-' : '') + Math.floor(Math.abs(d) / 60) + ':' + ('00' + Math.floor(Math.abs(d) % 60)).substr(-2, 2)
|
time: (d) => (d < 0 ? '-' : '') + Math.floor(Math.abs(d) / 60) + ':' + ('00' + Math.floor(Math.abs(d) % 60)).substr(-2, 2)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ export const terms = {
|
|||||||
cs: 'Cargo Scanner',
|
cs: 'Cargo Scanner',
|
||||||
dc: 'Docking Computer',
|
dc: 'Docking Computer',
|
||||||
fc: 'Fragment Cannon',
|
fc: 'Fragment Cannon',
|
||||||
|
fh: 'Fighter Hangar',
|
||||||
fi: 'FSD Interdictor',
|
fi: 'FSD Interdictor',
|
||||||
fs: 'Fuel Scoop',
|
fs: 'Fuel Scoop',
|
||||||
fsd: 'Frame Shift Drive',
|
fsd: 'Frame Shift Drive',
|
||||||
@@ -58,6 +59,10 @@ export const terms = {
|
|||||||
pa: 'Plasma Accelerator',
|
pa: 'Plasma Accelerator',
|
||||||
pas: 'Planetary Approach Suite',
|
pas: 'Planetary Approach Suite',
|
||||||
pc: 'Prospector Limpet Controller',
|
pc: 'Prospector Limpet Controller',
|
||||||
|
pce: 'Economy Class Passenger Cabin',
|
||||||
|
pci: 'Business Class Passenger Cabin',
|
||||||
|
pcm: 'First Class Passenger Cabin',
|
||||||
|
pcq: 'Luxury Passenger Cabin',
|
||||||
pd: 'power distributor',
|
pd: 'power distributor',
|
||||||
pl: 'Pulse Laser',
|
pl: 'Pulse Laser',
|
||||||
pp: 'Power Plant',
|
pp: 'Power Plant',
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class AboutPage extends Page {
|
|||||||
<p>This is a clone of the Coriolis project, whose original author is currently unable to maintain it. This clone is maintained by the <a href="http://edcd.github.io/">EDCD community</a>.</p>
|
<p>This is a clone of the Coriolis project, whose original author is currently unable to maintain it. This clone is maintained by the <a href="http://edcd.github.io/">EDCD community</a>.</p>
|
||||||
<p>To recover your builds, go to <a href='https://coriolis.io/' target='_blank'>https://coriolis.io/</a>, backup your builds (Settings / Backup), copy the text, return here and import (Settings / Import).</p>
|
<p>To recover your builds, go to <a href='https://coriolis.io/' target='_blank'>https://coriolis.io/</a>, backup your builds (Settings / Backup), copy the text, return here and import (Settings / Import).</p>
|
||||||
<p>The Coriolis project was inspired by <a href='http://www.edshipyard.com/' target='_blank'>E:D Shipyard</a> and, of course, <a href='http://www.elitedangerous.com' target='_blank'>Elite Dangerous</a>. The ultimate goal of Coriolis is to provide rich features to support in-game play and planning while engaging the E:D community to support its development.</p>
|
<p>The Coriolis project was inspired by <a href='http://www.edshipyard.com/' target='_blank'>E:D Shipyard</a> and, of course, <a href='http://www.elitedangerous.com' target='_blank'>Elite Dangerous</a>. The ultimate goal of Coriolis is to provide rich features to support in-game play and planning while engaging the E:D community to support its development.</p>
|
||||||
<p>Coriolis was created using assets and imagery from Elite: Dangerous, with the permission of Frontier Developments plc, for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments.</p>
|
<p>Coriolis was created using assets and imagery from Elite: Dangerous, with the permission of Frontier Developments plc, for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments. A number of assets were sourced from <a href='http://edassets.org' target='_blank'>ED Assets</a></p>
|
||||||
|
|
||||||
<a style={{ display: 'block', textDecoration: 'none' }} href='https://github.com/EDCD/coriolis' target='_blank' title='Coriolis Github Project'>
|
<a style={{ display: 'block', textDecoration: 'none' }} href='https://github.com/EDCD/coriolis' target='_blank' title='Coriolis Github Project'>
|
||||||
<GitHub style={{ margin: '0.4em' }} className='l fg xl'/>
|
<GitHub style={{ margin: '0.4em' }} className='l fg xl'/>
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ export default class OutfittingPage extends Page {
|
|||||||
<div id='overview'>
|
<div id='overview'>
|
||||||
<h1>{ship.name}</h1>
|
<h1>{ship.name}</h1>
|
||||||
<div id='build'>
|
<div id='build'>
|
||||||
<input value={newBuildName} onChange={this._buildNameChange} placeholder={translate('Enter Name')} maxsize={50} />
|
<input value={newBuildName} onChange={this._buildNameChange} placeholder={translate('Enter Name')} maxLength={50} />
|
||||||
<button onClick={canSave && this._saveBuild} disabled={!canSave} onMouseOver={termtip.bind(null, 'save')} onMouseOut={hide}>
|
<button onClick={canSave && this._saveBuild} disabled={!canSave} onMouseOver={termtip.bind(null, 'save')} onMouseOut={hide}>
|
||||||
<FloppyDisk className='lg' />
|
<FloppyDisk className='lg' />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ 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.1. For more info see Settings / <Link href="/about" className='block'>About</Link></p>
|
<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>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const ModuleGroupToName = {
|
|||||||
am: 'Auto Field-Maintenance Unit',
|
am: 'Auto Field-Maintenance Unit',
|
||||||
bsg: 'Bi-Weave Shield Generator',
|
bsg: 'Bi-Weave Shield Generator',
|
||||||
cr: 'Cargo Rack',
|
cr: 'Cargo Rack',
|
||||||
|
fh: 'Fighter Hangar',
|
||||||
fi: 'Frame Shift Drive Interdictor',
|
fi: 'Frame Shift Drive Interdictor',
|
||||||
hb: 'Hatch Breaker Limpet Controller',
|
hb: 'Hatch Breaker Limpet Controller',
|
||||||
hr: 'Hull Reinforcement Package',
|
hr: 'Hull Reinforcement Package',
|
||||||
@@ -48,6 +49,10 @@ export const ModuleGroupToName = {
|
|||||||
dc: 'Docking Computer',
|
dc: 'Docking Computer',
|
||||||
fx: 'Fuel Transfer Limpet Controller',
|
fx: 'Fuel Transfer Limpet Controller',
|
||||||
pc: 'Prospector Limpet Controller',
|
pc: 'Prospector Limpet Controller',
|
||||||
|
pce: 'Economy Class Passenger Cabin',
|
||||||
|
pci: 'Business Class Passenger Cabin',
|
||||||
|
pcm: 'First Class Passenger Cabin',
|
||||||
|
pcq: 'Luxury Passenger Cabin',
|
||||||
cc: 'Collector Limpet Controller',
|
cc: 'Collector Limpet Controller',
|
||||||
|
|
||||||
// Hard Points
|
// Hard Points
|
||||||
|
|||||||
@@ -71,16 +71,23 @@ export default class ModuleSet {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the modules that areeligible for an internal slot
|
* Determine the modules that areeligible for an internal slot
|
||||||
|
* @param {Object} ship The ship
|
||||||
* @param {integer} c The max class module that can be mounted in the slot
|
* @param {integer} c The max class module that can be mounted in the slot
|
||||||
* @param {Object} eligible) The map of eligible internal groups
|
* @param {Object} eligible) The map of eligible internal groups
|
||||||
* @return {object} A map of all eligible modules by group
|
* @return {object} A map of all eligible modules by group
|
||||||
*/
|
*/
|
||||||
getInts(c, eligible) {
|
getInts(ship, c, eligible) {
|
||||||
let o = {};
|
let o = {};
|
||||||
for (let key in this.internal) {
|
for (let key in this.internal) {
|
||||||
if (eligible && !eligible[key]) {
|
if (eligible && !eligible[key]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (key == 'pcq' && !(ship.luxuryCabins && ship.luxuryCabins === true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key == 'fh' && !(ship.fighterHangars && ship.fighterHangars === true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let data = filter(this.internal[key], c, 0, this.mass);
|
let data = filter(this.internal[key], c, 0, this.mass);
|
||||||
if (data.length) { // If group is not empty
|
if (data.length) { // If group is not empty
|
||||||
o[key] = data;
|
o[key] = data;
|
||||||
|
|||||||
@@ -6,6 +6,29 @@ import LZString from 'lz-string';
|
|||||||
|
|
||||||
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates ship-loadout JSON Schema standard object
|
||||||
|
* @param {Object} standard model
|
||||||
|
* @return {Object} JSON Schema
|
||||||
|
*/
|
||||||
|
function standardToSchema(standard) {
|
||||||
|
if (standard.m) {
|
||||||
|
let o = {
|
||||||
|
class: standard.m.class,
|
||||||
|
rating: standard.m.rating,
|
||||||
|
enabled: Boolean(standard.enabled),
|
||||||
|
priority: standard.priority + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (standard.m.name) {
|
||||||
|
o.name = standard.m.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ship-loadout JSON Schema slot object
|
* Generates ship-loadout JSON Schema slot object
|
||||||
* @param {Object} slot Slot model
|
* @param {Object} slot Slot model
|
||||||
@@ -61,13 +84,13 @@ export function toDetailedBuild(buildName, ship) {
|
|||||||
standard: {
|
standard: {
|
||||||
bulkheads: BulkheadNames[ship.bulkheads.m.index],
|
bulkheads: BulkheadNames[ship.bulkheads.m.index],
|
||||||
cargoHatch: { enabled: Boolean(ship.cargoHatch.enabled), priority: ship.cargoHatch.priority + 1 },
|
cargoHatch: { enabled: Boolean(ship.cargoHatch.enabled), priority: ship.cargoHatch.priority + 1 },
|
||||||
powerPlant: { class: standard[0].m.class, rating: standard[0].m.rating, enabled: Boolean(standard[0].enabled), priority: standard[0].priority + 1 },
|
powerPlant: standardToSchema(standard[0]),
|
||||||
thrusters: { class: standard[1].m.class, rating: standard[1].m.rating, enabled: Boolean(standard[1].enabled), priority: standard[1].priority + 1 },
|
thrusters: standardToSchema(standard[1]),
|
||||||
frameShiftDrive: { class: standard[2].m.class, rating: standard[2].m.rating, enabled: Boolean(standard[2].enabled), priority: standard[2].priority + 1 },
|
frameShiftDrive: standardToSchema(standard[2]),
|
||||||
lifeSupport: { class: standard[3].m.class, rating: standard[3].m.rating, enabled: Boolean(standard[3].enabled), priority: standard[3].priority + 1 },
|
lifeSupport: standardToSchema(standard[3]),
|
||||||
powerDistributor: { class: standard[4].m.class, rating: standard[4].m.rating, enabled: Boolean(standard[4].enabled), priority: standard[4].priority + 1 },
|
powerDistributor: standardToSchema(standard[4]),
|
||||||
sensors: { class: standard[5].m.class, rating: standard[5].m.rating, enabled: Boolean(standard[5].enabled), priority: standard[5].priority + 1 },
|
sensors: standardToSchema(standard[5]),
|
||||||
fuelTank: { class: standard[6].m.class, rating: standard[6].m.rating, enabled: Boolean(standard[6].enabled), priority: standard[6].priority + 1 }
|
fuelTank: standardToSchema(standard[6])
|
||||||
},
|
},
|
||||||
hardpoints: hardpoints.filter(slot => slot.maxClass > 0).map(slotToSchema),
|
hardpoints: hardpoints.filter(slot => slot.maxClass > 0).map(slotToSchema),
|
||||||
utility: hardpoints.filter(slot => slot.maxClass === 0).map(slotToSchema),
|
utility: hardpoints.filter(slot => slot.maxClass === 0).map(slotToSchema),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as Calc from './Calculations';
|
|||||||
import * as ModuleUtils from './ModuleUtils';
|
import * as ModuleUtils from './ModuleUtils';
|
||||||
import LZString from 'lz-string';
|
import LZString from 'lz-string';
|
||||||
|
|
||||||
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs'];
|
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the power usage type of a slot and it's particular modul
|
* Returns the power usage type of a slot and it's particular modul
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
|||||||
|
|
||||||
if (shielded) {
|
if (shielded) {
|
||||||
ship.internal.some(function(slot) {
|
ship.internal.some(function(slot) {
|
||||||
if (canMount(slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||||
ship.setSlotEnabled(slot, true);
|
ship.setSlotEnabled(slot, true);
|
||||||
return true;
|
return true;
|
||||||
@@ -35,7 +35,7 @@ export function trader(ship, shielded, standardOpts) {
|
|||||||
|
|
||||||
for (let i = ship.internal.length; i--;) {
|
for (let i = ship.internal.length; i--;) {
|
||||||
let slot = ship.internal[i];
|
let slot = ship.internal[i];
|
||||||
if (sg && canMount(slot, 'sg', sg.class)) {
|
if (sg && canMount(ship, slot, 'sg', sg.class)) {
|
||||||
ship.use(slot, sg);
|
ship.use(slot, sg);
|
||||||
sg = null;
|
sg = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -77,23 +77,23 @@ export function explorer(ship, planetary) {
|
|||||||
let slot = ship.internal[i];
|
let slot = ship.internal[i];
|
||||||
let nextSlot = (i + 1) < intLength ? ship.internal[i + 1] : null;
|
let nextSlot = (i + 1) < intLength ? ship.internal[i + 1] : null;
|
||||||
// Fit best possible Fuel Scoop
|
// Fit best possible Fuel Scoop
|
||||||
if (!fuelScoopSlot && canMount(slot, 'fs')) {
|
if (!fuelScoopSlot && canMount(ship, slot, 'fs')) {
|
||||||
fuelScoopSlot = slot;
|
fuelScoopSlot = slot;
|
||||||
ship.use(slot, ModuleUtils.findInternal('fs', slot.maxClass, 'A'));
|
ship.use(slot, ModuleUtils.findInternal('fs', slot.maxClass, 'A'));
|
||||||
ship.setSlotEnabled(slot, true);
|
ship.setSlotEnabled(slot, true);
|
||||||
// Mount a Shield generator if possible AND an AFM Unit has been mounted already (Guarantees at least 1 AFM Unit)
|
// Mount a Shield generator if possible AND an AFM Unit has been mounted already (Guarantees at least 1 AFM Unit)
|
||||||
} else if (!sgSlot && shieldNext && canMount(slot, 'sg', sg.class) && !canMount(nextSlot, 'sg', sg.class)) {
|
} else if (!sgSlot && shieldNext && canMount(ship, slot, 'sg', sg.class) && !canMount(ship, nextSlot, 'sg', sg.class)) {
|
||||||
sgSlot = slot;
|
sgSlot = slot;
|
||||||
shieldNext = false;
|
shieldNext = false;
|
||||||
ship.use(slot, sg);
|
ship.use(slot, sg);
|
||||||
ship.setSlotEnabled(slot, true);
|
ship.setSlotEnabled(slot, true);
|
||||||
// if planetary explorer and the next slot cannot mount a PVH or the next modul to mount is a SG
|
// if planetary explorer and the next slot cannot mount a PVH or the next modul to mount is a SG
|
||||||
} else if (planetary && !pvhSlot && canMount(slot, 'pv') && (shieldNext || !canMount(nextSlot, 'pv', 2))) {
|
} else if (planetary && !pvhSlot && canMount(ship, slot, 'pv') && (shieldNext || !canMount(ship, nextSlot, 'pv', 2))) {
|
||||||
pvhSlot = slot;
|
pvhSlot = slot;
|
||||||
ship.use(slot, ModuleUtils.findInternal('pv', Math.min(Math.floor(pvhSlot.maxClass / 2) * 2, 6), 'G'));
|
ship.use(slot, ModuleUtils.findInternal('pv', Math.min(Math.floor(pvhSlot.maxClass / 2) * 2, 6), 'G'));
|
||||||
ship.setSlotEnabled(slot, false); // Disabled power for PVH
|
ship.setSlotEnabled(slot, false); // Disabled power for PVH
|
||||||
shieldNext = !sgSlot;
|
shieldNext = !sgSlot;
|
||||||
} else if (afmUnitCount > 0 && canMount(slot, 'am')) {
|
} else if (afmUnitCount > 0 && canMount(ship, slot, 'am')) {
|
||||||
afmUnitCount--;
|
afmUnitCount--;
|
||||||
ship.use(slot, ModuleUtils.findInternal('am', slot.maxClass, 'A'));
|
ship.use(slot, ModuleUtils.findInternal('am', slot.maxClass, 'A'));
|
||||||
ship.setSlotEnabled(slot, false); // Disabled power for AFM Unit
|
ship.setSlotEnabled(slot, false); // Disabled power for AFM Unit
|
||||||
|
|||||||
@@ -5,14 +5,19 @@ import { Infinite } from '../components/SvgIcons';
|
|||||||
import Persist from '../stores/Persist';
|
import Persist from '../stores/Persist';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if a slot can mount a module of a particular class and group
|
* Determine if a slot on a ship can mount a module of a particular class and group
|
||||||
|
* @param {Object} ship Ship object
|
||||||
* @param {Object} slot Slot object
|
* @param {Object} slot Slot object
|
||||||
* @param {String} group Module group/type abbrivation/code
|
* @param {String} group Module group/type abbrivation/code
|
||||||
* @param {Integer} clazz [Optional] Module Class/Size
|
* @param {Integer} clazz [Optional] Module Class/Size
|
||||||
* @return {Boolean} True if the slot can mount the module
|
* @return {Boolean} True if the slot can mount the module
|
||||||
*/
|
*/
|
||||||
export function canMount(slot, group, clazz) {
|
export function canMount(ship, slot, group, clazz) {
|
||||||
if (slot && (!slot.eligible || slot.eligible[group]) && (clazz === undefined || slot.maxClass >= clazz)) {
|
if (slot &&
|
||||||
|
(!slot.eligible || slot.eligible[group]) &&
|
||||||
|
(group != 'pcq' || (ship.luxuryCabins && ship.luxuryCabins === true)) &&
|
||||||
|
(group != 'fh' || (ship.fighterHangars && ship.fighterHangars === true)) &&
|
||||||
|
(clazz === undefined || slot.maxClass >= clazz)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -122,7 +127,11 @@ const PROP_BLACKLIST = {
|
|||||||
enginecapacity: 1,
|
enginecapacity: 1,
|
||||||
enginerecharge: 1,
|
enginerecharge: 1,
|
||||||
systemcapacity: 1,
|
systemcapacity: 1,
|
||||||
systemrecharge: 1
|
systemrecharge: 1,
|
||||||
|
breachdps: 1,
|
||||||
|
breachmin: 1,
|
||||||
|
breachmax: 1,
|
||||||
|
integrity: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
const TERM_LOOKUP = {
|
const TERM_LOOKUP = {
|
||||||
@@ -175,7 +184,7 @@ function diffClass(a, b, negative) {
|
|||||||
*/
|
*/
|
||||||
function diff(format, mVal, mmVal) {
|
function diff(format, mVal, mmVal) {
|
||||||
if (mVal == Infinity) {
|
if (mVal == Infinity) {
|
||||||
return <Infinite/>;
|
return '∞';
|
||||||
} else {
|
} else {
|
||||||
let diff = mVal - mmVal;
|
let diff = mVal - mmVal;
|
||||||
if (!diff || mVal === undefined || diff == mVal || Math.abs(diff) == Infinity) {
|
if (!diff || mVal === undefined || diff == mVal || Math.abs(diff) == Infinity) {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
background-color: @primary-bg;
|
background-color: @primary-bg;
|
||||||
border: 1px solid @primary-disabled;
|
border: 1px solid @primary-disabled;
|
||||||
color: @fg;
|
color: @fg;
|
||||||
|
stroke: @fg;
|
||||||
|
stroke-width: 20;
|
||||||
fill: @fg;
|
fill: @fg;
|
||||||
|
|
||||||
.details-container {
|
.details-container {
|
||||||
@@ -54,6 +56,8 @@
|
|||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
width: 1.2em;
|
width: 1.2em;
|
||||||
color: @primary-disabled;
|
color: @primary-disabled;
|
||||||
|
stroke: @primary-disabled;
|
||||||
|
stroke-width: 20;
|
||||||
border-right: 1px solid @primary-disabled;
|
border-right: 1px solid @primary-disabled;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding-top: 0.2em;
|
padding-top: 0.2em;
|
||||||
@@ -64,6 +68,8 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
color: lighten(@primary-bg, 12%);
|
color: lighten(@primary-bg, 12%);
|
||||||
|
stroke: lighten(@primary-bg, 12%);
|
||||||
|
stroke-width: 20;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
letter-spacing: 0.1em;
|
letter-spacing: 0.1em;
|
||||||
line-height: 1.7em;
|
line-height: 1.7em;
|
||||||
@@ -71,12 +77,16 @@
|
|||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
color: @primary-bg;
|
color: @primary-bg;
|
||||||
|
stroke: @primary-bg;
|
||||||
|
stroke-width: 20;
|
||||||
fill: @primary-bg;
|
fill: @primary-bg;
|
||||||
background-color: @primary;
|
background-color: @primary;
|
||||||
border: 1px solid @primary;
|
border: 1px solid @primary;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
.sz {
|
.sz {
|
||||||
color: @primary;
|
color: @primary;
|
||||||
|
stroke: @primary;
|
||||||
|
stroke-width: 20;
|
||||||
background-color: @primary-bg;
|
background-color: @primary-bg;
|
||||||
border-right: 1px solid @primary;
|
border-right: 1px solid @primary;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,11 @@
|
|||||||
"class": { "type": "integer", "minimum": 2, "maximum": 8 },
|
"class": { "type": "integer", "minimum": 2, "maximum": 8 },
|
||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 }
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"name": {
|
||||||
|
"description": "The name identifing the thrusters (if applicable), e.g. 'Enhanced Performance'",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"frameShiftDrive": {
|
"frameShiftDrive": {
|
||||||
|
|||||||
Reference in New Issue
Block a user