mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3bc900f16 | ||
|
|
38842417b0 | ||
|
|
82d485a98e | ||
|
|
fac71feea7 | ||
|
|
ec148847a9 | ||
|
|
445c63878b | ||
|
|
0474af912a | ||
|
|
7df5953824 | ||
|
|
e391b563fb | ||
|
|
53f62f96d0 | ||
|
|
18745979a0 | ||
|
|
c1966a38ff | ||
|
|
d86973f3b1 | ||
|
|
56b8d19649 | ||
|
|
7cb037e0bc | ||
|
|
56e1b3f9e9 | ||
|
|
c792323a8a | ||
|
|
4d2865de13 | ||
|
|
0d360bc367 | ||
|
|
91c9b46b91 | ||
|
|
7e67bd80dd | ||
|
|
2f775ea09b | ||
|
|
0603c55089 | ||
|
|
41f25a44e9 | ||
|
|
35440b7273 | ||
|
|
7d68b91018 | ||
|
|
deaa61b848 | ||
|
|
2d00cbc41b | ||
|
|
57c1e83c67 | ||
|
|
b7079dbd4e | ||
|
|
be642a5373 | ||
|
|
ffc691c1a2 | ||
|
|
6122d99369 | ||
|
|
b73a8bcdab | ||
|
|
dd624537b7 | ||
|
|
50a67f73fd | ||
|
|
2262a980d4 | ||
|
|
84964ceb5f | ||
|
|
c4bdb7a66e | ||
|
|
21309e129f | ||
|
|
928e02c718 | ||
|
|
7f494dd200 | ||
|
|
f38e743e59 | ||
|
|
58b55eb3da | ||
|
|
8375ad95b3 | ||
|
|
506d027a2d | ||
|
|
fbeb6237cf | ||
|
|
bd95e2c5a5 | ||
|
|
f3276e557a | ||
|
|
8b813e0e7f | ||
|
|
d660d2959f | ||
|
|
014ebda7d2 | ||
|
|
607398d364 | ||
|
|
97d141ce2b | ||
|
|
9f492db9c6 | ||
|
|
6ed82b366c | ||
|
|
a7ca037f48 | ||
|
|
6e21d0e74a | ||
|
|
e6c75bf2af | ||
|
|
270c2f386e | ||
|
|
83f7880c58 | ||
|
|
51d29aee38 | ||
|
|
c7754c0365 | ||
|
|
94037cea38 | ||
|
|
5c1a9d9eea | ||
|
|
3835c73ffd | ||
|
|
b8c1effecb | ||
|
|
dd07241dd9 | ||
|
|
5ad828a613 | ||
|
|
9856df5527 | ||
|
|
7b249900ec | ||
|
|
e3b9267c3f | ||
|
|
a996b8135a | ||
|
|
5e1237390b | ||
|
|
83571b4bef | ||
|
|
c2a0dad9a8 | ||
|
|
f6f057689c | ||
|
|
4378f0020e | ||
|
|
2e9e7c4fc6 | ||
|
|
b7b8ee5580 | ||
|
|
c630dbbed0 | ||
|
|
fa6703a3b8 | ||
|
|
bdcb64c9d1 | ||
|
|
a1afc869a7 | ||
|
|
d8ce26c7cf | ||
|
|
95c474dc05 | ||
|
|
56ca73b4ad | ||
|
|
d82cd6a89e | ||
|
|
bf20d32364 | ||
|
|
e968e62fca | ||
|
|
b9c9ca9fa1 | ||
|
|
6e965e2e98 | ||
|
|
7d569f9036 | ||
|
|
df5a77199d | ||
|
|
3c8dfebfdc | ||
|
|
3cc422596f | ||
|
|
4ed167de22 | ||
|
|
b420647501 | ||
|
|
0c318b5e68 | ||
|
|
1c627297b8 | ||
|
|
f41e2d0552 | ||
|
|
1a1d539c60 | ||
|
|
ba2e46f88f | ||
|
|
c2f1fa81af | ||
|
|
752e03fa0f | ||
|
|
1da69664d7 | ||
|
|
9aa986a133 | ||
|
|
bdbfb28c4a | ||
|
|
162156bb2b | ||
|
|
64c5d542e9 | ||
|
|
31dc789f6e | ||
|
|
b0e2cfd7db | ||
|
|
54ddb0d014 | ||
|
|
e19688e96f | ||
|
|
4f53d75999 | ||
|
|
93c4f6f3c0 |
21
.editorconfig
Normal file
21
.editorconfig
Normal file
@@ -0,0 +1,21 @@
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
10
ChangeLog.md
10
ChangeLog.md
@@ -1,3 +1,13 @@
|
||||
#2.5.1
|
||||
* Passenger count on main page
|
||||
* AX Modules
|
||||
* Engineering fixes
|
||||
* Use coriolis-data 2.5.1
|
||||
|
||||
#2.5.0
|
||||
* willyb321 and myself have conquered engineering. Mainly him though...
|
||||
* Use coriolis-data 2.5.0
|
||||
|
||||
#2.4.2
|
||||
Lots of kind people have helped out for this release! Check out the PR history!
|
||||
* Uses coriolis-data update:
|
||||
|
||||
1
devServer.js
Normal file → Executable file
1
devServer.js
Normal file → Executable file
@@ -5,6 +5,7 @@ var config = require('./webpack.config.dev');
|
||||
new WebpackDevServer(webpack(config), {
|
||||
publicPath: config.output.publicPath,
|
||||
hot: true,
|
||||
disableHostCheck: true,
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
|
||||
1565
package-lock.json
generated
1565
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "coriolis_shipyard",
|
||||
"version": "2.4.2",
|
||||
"version": "2.9.6",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EDCD/coriolis"
|
||||
@@ -19,7 +19,7 @@
|
||||
"test": "jest",
|
||||
"prod-serve": "nginx -p $(pwd) -c nginx.conf",
|
||||
"prod-stop": "kill -QUIT $(cat nginx.pid)",
|
||||
"build": "npm run clean && NODE_ENV=production webpack -p --config webpack.config.prod.js",
|
||||
"build": "npm run clean && cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js",
|
||||
"rsync": "rsync -ae \"ssh -i $CORIOLIS_PEM\" --delete build/ $CORIOLIS_USER@$CORIOLIS_HOST:~/wwws",
|
||||
"deploy": "npm run lint && npm test && npm run build && npm run rsync"
|
||||
},
|
||||
@@ -66,6 +66,7 @@
|
||||
"babel-preset-stage-0": "*",
|
||||
"create-react-class": "^15.6.2",
|
||||
"css-loader": "^0.28.0",
|
||||
"cross-env": "^5.1.4",
|
||||
"d3-selection": "1",
|
||||
"eslint": "3.19.0",
|
||||
"eslint-plugin-react": "^6.10.3",
|
||||
@@ -87,10 +88,12 @@
|
||||
"rollup": "0.41",
|
||||
"rollup-plugin-node-resolve": "3",
|
||||
"style-loader": "^0.16.1",
|
||||
"uglify-js": "^2.4.11",
|
||||
"url-loader": "^0.5.8",
|
||||
"webpack": "^2.4.1",
|
||||
"webpack-dev-server": "^2.4.4",
|
||||
"uglify-js": "^2.4.11"
|
||||
"webpack-notifier": "^1.6.0",
|
||||
"webpack-bugsnag-plugins": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "*",
|
||||
|
||||
@@ -12,6 +12,7 @@ import ModalHelp from './components/ModalHelp';
|
||||
import ModalImport from './components/ModalImport';
|
||||
import ModalPermalink from './components/ModalPermalink';
|
||||
import * as CompanionApiUtils from './utils/CompanionApiUtils';
|
||||
import * as JournalUtils from './utils/JournalUtils';
|
||||
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import NotFoundPage from './pages/NotFoundPage';
|
||||
@@ -92,7 +93,14 @@ export default class Coriolis extends React.Component {
|
||||
// Need to decode and gunzip the data, then build the ship
|
||||
const data = zlib.inflate(new Buffer(r.params.data, 'base64'), { to: 'string' });
|
||||
const json = JSON.parse(data);
|
||||
const ship = CompanionApiUtils.shipFromJson(json);
|
||||
console.log('Ship import data: ');
|
||||
console.log(json);
|
||||
let ship;
|
||||
if (json && json.modules) {
|
||||
ship = CompanionApiUtils.shipFromJson(json);
|
||||
} else if (json && json.Modules) {
|
||||
ship = JournalUtils.shipFromLoadoutJSON(json);
|
||||
}
|
||||
r.params.ship = ship.id;
|
||||
r.params.code = ship.toString();
|
||||
this._setPage(OutfittingPage, r);
|
||||
@@ -126,9 +134,9 @@ export default class Coriolis extends React.Component {
|
||||
console && console.error && console.error(arguments); // eslint-disable-line no-console
|
||||
if (errObj) {
|
||||
if (errObj instanceof Error) {
|
||||
Bugsnag.notifyException(errObj) // eslint-disable-line
|
||||
bugsnagClient.notify(errObj) // eslint-disable-line
|
||||
} else if (errObj instanceof String) {
|
||||
Bugsnag.notify(msg, errObj) // eslint-disable-line
|
||||
bugsnagClient.notify(msg, errObj) // eslint-disable-line
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
|
||||
@@ -37,10 +37,13 @@ const GRPCAT = {
|
||||
'ml': 'lasers',
|
||||
'c': 'projectiles',
|
||||
'mc': 'projectiles',
|
||||
'axmc': 'experimental',
|
||||
'fc': 'projectiles',
|
||||
'rfl': 'experimental',
|
||||
'pa': 'projectiles',
|
||||
'rg': 'projectiles',
|
||||
'mr': 'ordnance',
|
||||
'axmr': 'experimental',
|
||||
'tp': 'ordnance',
|
||||
'nl': 'ordnance',
|
||||
'sc': 'scanners',
|
||||
@@ -49,9 +52,11 @@ const GRPCAT = {
|
||||
'cs': 'scanners',
|
||||
'kw': 'scanners',
|
||||
'ws': 'scanners',
|
||||
'xs': 'scanners',
|
||||
'ch': 'defence',
|
||||
'po': 'defence',
|
||||
'ec': 'defence',
|
||||
'sfn': 'defence'
|
||||
};
|
||||
// Order here is the order in which items will be shown in the modules menu
|
||||
const CATEGORIES = {
|
||||
@@ -76,6 +81,8 @@ const CATEGORIES = {
|
||||
'hs': ['hs'],
|
||||
'defence': ['ch', 'po', 'ec'],
|
||||
'scanners': ['sc', 'ss', 'cs', 'kw', 'ws'], // Overloaded with internal scanners
|
||||
// Experimental
|
||||
'experimental': ['axmc', 'axmr', 'rfl', 'xs', 'sfn']
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ export default class EngagementRange extends TranslatedComponent {
|
||||
|
||||
const { ship } = props;
|
||||
|
||||
const maxRange = this._calcMaxRange(ship);
|
||||
const maxRange = Math.round(this._calcMaxRange(ship));
|
||||
|
||||
this.state = {
|
||||
maxRange
|
||||
|
||||
@@ -33,6 +33,9 @@ export default class InternalSlot extends Slot {
|
||||
let modTT = translate('modified');
|
||||
if (m && m.blueprint && m.blueprint.name) {
|
||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
||||
modTT += ', ' + translate(m.blueprint.special.name);
|
||||
}
|
||||
modTT = (
|
||||
<div>
|
||||
<div>{modTT}</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isEmpty, stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||
import cn from 'classnames';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
import Modification from './Modification';
|
||||
import { getBlueprint, blueprintTooltip, setWorst, setBest, setExtreme, setRandom } from '../utils/BlueprintFunctions';
|
||||
import { getBlueprint, blueprintTooltip, setPercent, setRandom } from '../utils/BlueprintFunctions';
|
||||
|
||||
/**
|
||||
* Modifications menu
|
||||
@@ -30,10 +30,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
|
||||
this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this);
|
||||
this._toggleSpecialsMenu = this._toggleSpecialsMenu.bind(this);
|
||||
this._rollWorst = this._rollWorst.bind(this);
|
||||
this._rollFifty = this._rollFifty.bind(this);
|
||||
this._rollRandom = this._rollRandom.bind(this);
|
||||
this._rollBest = this._rollBest.bind(this);
|
||||
this._rollExtreme = this._rollExtreme.bind(this);
|
||||
this._rollSevenFive = this._rollSevenFive.bind(this);
|
||||
this._reset = this._reset.bind(this);
|
||||
|
||||
this.state = {
|
||||
@@ -168,11 +168,11 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a 'worst' roll within the information we have
|
||||
* Provide a '50%' roll within the information we have
|
||||
*/
|
||||
_rollWorst() {
|
||||
_rollFifty() {
|
||||
const { m, ship } = this.props;
|
||||
setWorst(ship, m);
|
||||
setPercent(ship, m, 50);
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
@@ -190,16 +190,16 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
*/
|
||||
_rollBest() {
|
||||
const { m, ship } = this.props;
|
||||
setBest(ship, m);
|
||||
setPercent(ship, m, 100);
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an 'extreme' roll within the information we have
|
||||
* Provide an '75%' roll within the information we have
|
||||
*/
|
||||
_rollExtreme() {
|
||||
_rollSevenFive() {
|
||||
const { m, ship } = this.props;
|
||||
setExtreme(ship, m);
|
||||
setPercent(ship, m, 75);
|
||||
this.props.onChange();
|
||||
}
|
||||
|
||||
@@ -226,9 +226,9 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
|
||||
const _toggleBlueprintsMenu = this._toggleBlueprintsMenu;
|
||||
const _toggleSpecialsMenu = this._toggleSpecialsMenu;
|
||||
const _rollBest = this._rollBest;
|
||||
const _rollExtreme = this._rollExtreme;
|
||||
const _rollWorst = this._rollWorst;
|
||||
const _rollFull = this._rollBest;
|
||||
const _rollSevenFive = this._rollSevenFive;
|
||||
const _rollFifty = this._rollFifty;
|
||||
const _rollRandom = this._rollRandom;
|
||||
const _reset = this._reset;
|
||||
|
||||
@@ -275,9 +275,9 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
{ showRolls ?
|
||||
<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={_rollBest}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('best') } </td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={_rollExtreme}onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_EXTREME')} onMouseOut={tooltip.bind(null, null)}> { translate('extreme') } </td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={_rollFifty} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_FIFTY')} onMouseOut={tooltip.bind(null, null)}> { translate('50%') } </td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={_rollSevenFive} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_SEVEN_FIVE')} onMouseOut={tooltip.bind(null, null)}> { translate('75%') } </td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={_rollFull} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('100%') } </td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={_rollRandom} onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_RANDOM')} onMouseOut={tooltip.bind(null, null)}> { translate('random') } </td>
|
||||
</tr> : null }
|
||||
{ showReset ?
|
||||
|
||||
@@ -53,6 +53,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
<th rowSpan={2}>{translate('TTD')}</th>
|
||||
{/* <th onMouseEnter={termtip.bind(null, 'heat per second')} onMouseLeave={hide} rowSpan={2}>{translate('HPS')}</th> */}
|
||||
<th rowSpan={2}>{translate('cargo')}</th>
|
||||
<th rowSpan={2}>{translate('pax')}</th>
|
||||
<th rowSpan={2}>{translate('fuel')}</th>
|
||||
<th colSpan={3}>{translate('mass')}</th>
|
||||
<th onMouseEnter={termtip.bind(null, 'hull hardness', { cap: 0 })} onMouseLeave={hide} rowSpan={2}>{translate('hrd')}</th>
|
||||
@@ -86,6 +87,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
<td onMouseEnter={termtip.bind(null, 'TT_SUMMARY_TTD', { cap: 0 })} onMouseLeave={hide}>{timeToDrain === Infinity ? '∞' : time(timeToDrain)}</td>
|
||||
{/* <td>{f1(ship.totalHps)}</td> */}
|
||||
<td>{round(ship.cargoCapacity)}{u.T}</td>
|
||||
<td>{ship.passengerCapacity}</td>
|
||||
<td>{round(ship.fuelCapacity)}{u.T}</td>
|
||||
<td onMouseEnter={termtip.bind(null, 'TT_SUMMARY_HULL_MASS', { cap: 0 })} onMouseLeave={hide}>{ship.hullMass}{u.T}</td>
|
||||
<td onMouseEnter={termtip.bind(null, 'TT_SUMMARY_UNLADEN_MASS', { cap: 0 })} onMouseLeave={hide}>{int(ship.unladenMass)}{u.T}</td>
|
||||
|
||||
@@ -56,6 +56,9 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
let modTT = translate('modified');
|
||||
if (m && m.blueprint && m.blueprint.name) {
|
||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
||||
modTT += ', ' + translate(m.blueprint.special.name);
|
||||
}
|
||||
modTT = (
|
||||
<div>
|
||||
<div>{modTT}</div>
|
||||
@@ -96,7 +99,7 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
return (
|
||||
<div className={cn('slot', { selected: this.props.selected })} onClick={this.props.onOpen} onContextMenu={stopCtxPropagation}>
|
||||
<div className={cn('details-container', { warning: warning && warning(slot.m), disabled: m.grp !== 'bh' && !slot.enabled })}>
|
||||
<div className={'sz'}>{slot.maxClass}</div>
|
||||
<div className={'sz'}>{m.grp == 'bh' ? m.name.charAt(0) : slot.maxClass}</div>
|
||||
<div>
|
||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }</div>
|
||||
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
||||
|
||||
@@ -235,12 +235,10 @@ export default class StandardSlotSection extends SlotSection {
|
||||
<ul>
|
||||
<li className='lc' onClick={this._multiPurpose.bind(this, false, 0)}>{translate('Multi-purpose')}</li>
|
||||
<li className='lc' onClick={this._multiPurpose.bind(this, true, 2)}>{translate('Combat')}</li>
|
||||
<li className='lc' onClick={this._optimizeCargo.bind(this, false)}>{translate('Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeCargo.bind(this, true)}>{translate('Shielded Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeCargo.bind(this, true)}>{translate('Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeExplorer.bind(this, false)}>{translate('Explorer')}</li>
|
||||
<li className={cn('lc', { disabled: planetaryDisabled })} onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)}>{translate('Planetary Explorer')}</li>
|
||||
<li className='lc' onClick={this._optimizeMiner.bind(this, false)}>{translate('Miner')}</li>
|
||||
<li className='lc' onClick={this._optimizeMiner.bind(this, true)}>{translate('Shielded Miner')}</li>
|
||||
<li className='lc' onClick={this._optimizeMiner.bind(this, true)}>{translate('Miner')}</li>
|
||||
<li className='lc' onClick={this._optimizeRacer.bind(this)}>{translate('Racer')}</li>
|
||||
</ul>
|
||||
</div>;
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as FR from './fr';
|
||||
import * as IT from './it';
|
||||
import * as RU from './ru';
|
||||
import * as PL from './pl';
|
||||
import * as PT from './pt';
|
||||
import * as d3 from 'd3';
|
||||
|
||||
let fallbackTerms = EN.terms;
|
||||
@@ -25,6 +26,7 @@ export function getLanguage(langCode) {
|
||||
case 'it': lang = IT; break;
|
||||
case 'ru': lang = RU; break;
|
||||
case 'pl': lang = PL; break;
|
||||
case 'pt': lang = PT; break;
|
||||
default:
|
||||
lang = EN;
|
||||
}
|
||||
@@ -88,5 +90,6 @@ export const Languages = {
|
||||
es: 'Español',
|
||||
fr: 'Français',
|
||||
ru: 'ру́сский',
|
||||
pl: 'polski'
|
||||
pl: 'polski',
|
||||
pt: 'português'
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
"PHRASE_ENGAGEMENT_RANGE": "The distance between your ship and its target",
|
||||
"PHRASE_SELECT_BLUEPRINT": "Click to select a blueprint",
|
||||
"PHRASE_BLUEPRINT_WORST": "Worst primary values for this blueprint",
|
||||
"PHRASE_BLUEPRINT_FIFTY": "50% of full values for this blueprint",
|
||||
"PHRASE_BLUEPRINT_SEVEN_FIVE": "75% of full 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_EXTREME": "Best beneficial and worst detrimental primary values for this blueprint",
|
||||
@@ -98,8 +100,10 @@
|
||||
"kw": "Kill Warrant Scanner",
|
||||
"ls": "Life Support",
|
||||
"mc": "Multi-cannon",
|
||||
"axmc": "AX Multi-cannon",
|
||||
"ml": "Mining Laser",
|
||||
"mr": "Missile Rack",
|
||||
"axmr": "AX Missile Rack",
|
||||
"mrp": "Module Reinforcement Package",
|
||||
"nl": "Mine Launcher",
|
||||
"pa": "Plasma Accelerator",
|
||||
@@ -116,11 +120,13 @@
|
||||
"psg": "Prismatic Shield Generator",
|
||||
"pv": "Planetary Vehicle Hangar",
|
||||
"rf": "Refinery",
|
||||
"rfl": "Remote Release Flak Launcher",
|
||||
"rg": "Rail Gun",
|
||||
"s": "Sensors",
|
||||
"sb": "Shield Booster",
|
||||
"sc": "Stellar Scanners",
|
||||
"scb": "Shield Cell Bank",
|
||||
"sfn": "Shutdown Field Neutraliser",
|
||||
"sg": "Shield Generator",
|
||||
"ss": "Surface Scanners",
|
||||
"t": "thrusters",
|
||||
@@ -128,6 +134,7 @@
|
||||
"ul": "Burst Laser",
|
||||
"ws": "Frame Shift Wake Scanner",
|
||||
"rpl": "Repair Limpet Controller",
|
||||
"xs": "Xeno Scanner",
|
||||
"emptyrestricted": "empty (restricted)",
|
||||
"damage dealt to": "Damage dealt to",
|
||||
"damage received from": "Damage received from",
|
||||
|
||||
16
src/app/i18n/pt.js
Normal file
16
src/app/i18n/pt.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const formats = {
|
||||
decimal: ',',
|
||||
thousands: '.',
|
||||
grouping: [3],
|
||||
currency: ['', ' €'],
|
||||
dateTime: '%A, %e de %B de %Y, %X',
|
||||
date: '%d/%m/%Y',
|
||||
time: '%H:%M:%S',
|
||||
periods: ['AM', 'PM'],
|
||||
days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
|
||||
shortDays: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
|
||||
months: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
|
||||
shortMonths: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic']
|
||||
};
|
||||
|
||||
export { default as terms } from './pt.json';
|
||||
278
src/app/i18n/pt.json
Normal file
278
src/app/i18n/pt.json
Normal file
File diff suppressed because one or more lines are too long
@@ -41,6 +41,9 @@ export default class AboutPage extends Page {
|
||||
|
||||
<h3>Chat</h3>
|
||||
<p>You can chat to us on our <a href='https://discord.gg/0uwCh6R62aPRjk9w' target='_blank'>EDCD Discord server</a>.</p>
|
||||
|
||||
<h3>Supporting Coriolis</h3>
|
||||
<p>Coriolis is an open source project, and I work on it in my free time. I have set up a patreon at <a href='https://www.patreon.com/coriolis_elite'>patreon.com/coriolis_elite</a>, which will be used to keep Coriolis up to date and the servers running.</p>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,10 @@ export default class OutfittingPage extends Page {
|
||||
let buildName = params.bn;
|
||||
let data = Ships[shipId]; // Retrieve the basic ship properties, slots and defaults
|
||||
let savedCode = Persist.getBuild(shipId, buildName);
|
||||
|
||||
if (!data) {
|
||||
return { error: { message: 'Ship not found: ' + shipId } };
|
||||
}
|
||||
|
||||
let ship = new Ship(shipId, data.properties, data.slots); // Create a new Ship instance
|
||||
|
||||
if (code) {
|
||||
ship.buildFrom(code); // Populate modules from serialized 'code' URL param
|
||||
} else {
|
||||
|
||||
@@ -25,6 +25,25 @@ function countInt(slot) {
|
||||
this.int[slot.maxClass - 1]++; // Subtract 1 since there is no Class 0 Internal compartment
|
||||
this.intCount++;
|
||||
this.maxCargo += crEligible ? ModuleUtils.findInternal('cr', slot.maxClass, 'E').cargo : 0;
|
||||
|
||||
// if no eligiblity, then assume pce
|
||||
let passSlotType = null;
|
||||
let passSlotRating = null;
|
||||
if (!slot.eligible || slot.eligible.pce) {
|
||||
passSlotType = 'pce';
|
||||
passSlotRating = 'E';
|
||||
} else if (slot.eligible.pci) {
|
||||
passSlotType = 'pci';
|
||||
passSlotRating = 'D';
|
||||
} else if (slot.eligible.pcm) {
|
||||
passSlotType = 'pcm';
|
||||
passSlotRating = 'C';
|
||||
} else if (slot.eligible.pcq) {
|
||||
passSlotType = 'pcq';
|
||||
passSlotRating = 'B';
|
||||
}
|
||||
let passengerBay = passSlotType ? ModuleUtils.findMaxInternal(passSlotType, slot.maxClass, passSlotRating) : null;
|
||||
this.maxPassengers += passengerBay ? passengerBay.passengers : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +58,7 @@ function shipSummary(shipId, shipData) {
|
||||
hpCount: 0,
|
||||
intCount: 0,
|
||||
maxCargo: 0,
|
||||
maxPassengers: 0,
|
||||
hp: [0, 0, 0, 0, 0], // Utility, Small, Medium, Large, Huge
|
||||
int: [0, 0, 0, 0, 0, 0, 0, 0], // Sizes 1 - 8
|
||||
standard: shipData.slots.standard,
|
||||
@@ -139,15 +159,16 @@ export default class ShipyardPage extends Page {
|
||||
* @param {Object} u Localized unit map
|
||||
* @param {Function} fInt Localized integer formatter
|
||||
* @param {Function} fRound Localized round formatter
|
||||
* @param {Boolean} highlight Should this row be highlighted
|
||||
* @return {React.Component} Table Row
|
||||
*/
|
||||
_shipRowElement(s, translate, u, fInt, fRound) {
|
||||
_shipRowElement(s, translate, u, fInt, fRound, highlight) {
|
||||
let noTouch = this.context.noTouch;
|
||||
|
||||
return <tr
|
||||
key={s.id}
|
||||
style={{ height: '1.5em' }}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id })}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id, alt: highlight })}
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className='ri'>{s.manufacturer}</td>
|
||||
@@ -166,12 +187,14 @@ export default class ShipyardPage extends Page {
|
||||
<td className='ri'>{fInt(s.topBoost)}</td>
|
||||
<td className='ri'>{fRound(s.maxJumpRange)}</td>
|
||||
<td className='ri'>{fInt(s.maxCargo)}</td>
|
||||
<td className='ri'>{fInt(s.maxPassengers)}</td>
|
||||
<td className='cn'>{s.standard[0]}</td>
|
||||
<td className='cn'>{s.standard[1]}</td>
|
||||
<td className='cn'>{s.standard[2]}</td>
|
||||
<td className='cn'>{s.standard[3]}</td>
|
||||
<td className='cn'>{s.standard[4]}</td>
|
||||
<td className='cn'>{s.standard[5]}</td>
|
||||
<td className='cn'>{s.standard[6]}</td>
|
||||
<td className={cn({ disabled: !s.hp[1] })}>{s.hp[1]}</td>
|
||||
<td className={cn({ disabled: !s.hp[2] })}>{s.hp[2]}</td>
|
||||
<td className={cn({ disabled: !s.hp[3] })}>{s.hp[3]}</td>
|
||||
@@ -246,13 +269,26 @@ export default class ShipyardPage extends Page {
|
||||
let shipRows = new Array(shipSummaries.length);
|
||||
let detailRows = new Array(shipSummaries.length);
|
||||
|
||||
let lastShipSortValue = null;
|
||||
let backgroundHighlight = false;
|
||||
|
||||
for (let s of shipSummaries) {
|
||||
detailRows[i] = this._shipRowElement(s, translate, units, fInt, formats.f1);
|
||||
let shipSortValue = s[shipPredicate];
|
||||
if( shipPredicateIndex != undefined ) {
|
||||
shipSortValue = shipSortValue[shipPredicateIndex];
|
||||
}
|
||||
|
||||
if( shipSortValue != lastShipSortValue ) {
|
||||
backgroundHighlight = !backgroundHighlight;
|
||||
lastShipSortValue = shipSortValue;
|
||||
}
|
||||
|
||||
detailRows[i] = this._shipRowElement(s, translate, units, fInt, formats.f1, backgroundHighlight);
|
||||
shipRows[i] = (
|
||||
<tr
|
||||
key={i}
|
||||
style={{ height: '1.5em' }}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id })}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id, alt: backgroundHighlight })}
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className='le'><Link href={'/outfit/' + s.id}>{s.name}</Link></td>
|
||||
@@ -293,8 +329,8 @@ export default class ShipyardPage extends Page {
|
||||
<th rowSpan={3} className='sortable' onMouseEnter={termtip.bind(null, 'hardness')} onMouseLeave={hide} onClick={sortShips('hardness')}>{translate('hrd')}</th>
|
||||
<th> </th>
|
||||
<th colSpan={4}>{translate('base')}</th>
|
||||
<th colSpan={4}>{translate('max')}</th>
|
||||
<th className='lft' colSpan={6}></th>
|
||||
<th colSpan={5}>{translate('max')}</th>
|
||||
<th className='lft' colSpan={7}></th>
|
||||
<th className='lft' colSpan={5}></th>
|
||||
<th className='lft' colSpan={8}></th>
|
||||
</tr>
|
||||
@@ -310,29 +346,31 @@ export default class ShipyardPage extends Page {
|
||||
<th className='sortable' onClick={sortShips('topBoost')}>{translate('boost')}</th>
|
||||
<th className='sortable' onClick={sortShips('maxJumpRange')}>{translate('jump')}</th>
|
||||
<th className='sortable' onClick={sortShips('maxCargo')}>{translate('cargo')}</th>
|
||||
<th className='sortable' onClick={sortShips('maxPassengers')}>{translate('pax')}</th>
|
||||
|
||||
<th className='lft' colSpan={6}>{translate('core module classes')}</th>
|
||||
<th className='lft' colSpan={7}>{translate('core module classes')}</th>
|
||||
<th colSpan={5} className='sortable lft' onClick={sortShips('hpCount')}>{translate('hardpoints')}</th>
|
||||
<th colSpan={8} className='sortable lft' onClick={sortShips('intCount')}>{translate('internal compartments')}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th className='sortable lft' onClick={sortShips('retailCost')}>{units.CR}</th>
|
||||
<th className='sortable lft' onClick={sortShips('hullMass')}>{units.T}</th>
|
||||
<th className='sortable lft' onClick={sortShips('speed')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('boost')}>{units['m/s']}</th>
|
||||
<th> </th>
|
||||
<th className='sortable' onClick={sortShips('baseShieldStrength')}>{units.MJ}</th>
|
||||
<th className='sortable lft' onClick={sortShips('topSpeed')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('topBoost')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('maxJumpRange')}>{units.LY}</th>
|
||||
<th className='sortable' onClick={sortShips('maxCargo')}>{units.T}</th>
|
||||
<th className='sortable lft' onClick={sortShips('retailCost')}>{units.CR}</th>
|
||||
<th className='sortable lft' onClick={sortShips('hullMass')}>{units.T}</th>
|
||||
<th className='sortable lft' onClick={sortShips('speed')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('boost')}>{units['m/s']}</th>
|
||||
<th> </th>
|
||||
<th className='sortable' onClick={sortShips('baseShieldStrength')}>{units.MJ}</th>
|
||||
<th className='sortable lft' onClick={sortShips('topSpeed')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('topBoost')}>{units['m/s']}</th>
|
||||
<th className='sortable' onClick={sortShips('maxJumpRange')}>{units.LY}</th>
|
||||
<th className='sortable' onClick={sortShips('maxCargo')}>{units.T}</th>
|
||||
<th> </th>
|
||||
<th className='sortable lft' onMouseEnter={termtip.bind(null, 'power plant')} onMouseLeave={hide} onClick={sortShips('standard', 0)}>{'pp'}</th>
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'thrusters')} onMouseLeave={hide} onClick={sortShips('standard', 1)}>{'th'}</th>
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'frame shift drive')} onMouseLeave={hide} onClick={sortShips('standard', 2)}>{'fsd'}</th>
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'life support')} onMouseLeave={hide} onClick={sortShips('standard', 3)}>{'ls'}</th>
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'power distriubtor')} onMouseLeave={hide} onClick={sortShips('standard', 4)}>{'pd'}</th>
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'sensors')} onMouseLeave={hide} onClick={sortShips('standard', 5)}>{'s'}</th>
|
||||
|
||||
<th className='sortable' onMouseEnter={termtip.bind(null, 'fuel tank')} onMouseLeave={hide} onClick={sortShips('standard', 6)}>{'ft'}</th>
|
||||
<th className='sortable lft' onClick={sortShips('hp',1)}>{translate('S')}</th>
|
||||
<th className='sortable' onClick={sortShips('hp', 2)}>{translate('M')}</th>
|
||||
<th className='sortable' onClick={sortShips('hp', 3)}>{translate('L')}</th>
|
||||
@@ -358,4 +396,4 @@ export default class ShipyardPage extends Page {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,19 +58,24 @@ export const ModuleGroupToName = {
|
||||
cm: 'Countermeasure',
|
||||
ec: 'Electronic Countermeasure',
|
||||
fc: 'Fragment Cannon',
|
||||
rfl: 'Remote Release Flak Launcher',
|
||||
hs: 'Heat Sink Launcher',
|
||||
ws: 'Frame Shift Wake Scanner',
|
||||
kw: 'Kill Warrant Scanner',
|
||||
nl: 'Mine Launcher',
|
||||
ml: 'Mining Laser',
|
||||
mr: 'Missile Rack',
|
||||
axmr: 'AX Missile Rack',
|
||||
pa: 'Plasma Accelerator',
|
||||
po: 'Point Defence',
|
||||
mc: 'Multi-cannon',
|
||||
axmc: 'AX Multi-cannon',
|
||||
pl: 'Pulse Laser',
|
||||
rg: 'Rail Gun',
|
||||
sb: 'Shield Booster',
|
||||
tp: 'Torpedo Pylon'
|
||||
tp: 'Torpedo Pylon',
|
||||
sfn: 'Shutdown Field Neutraliser',
|
||||
xs: 'Xeno Scanner'
|
||||
};
|
||||
|
||||
let GrpNameToCodeMap = {};
|
||||
|
||||
@@ -64,7 +64,6 @@ export default class Module {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sanitise the resultant value to 4dp equivalent
|
||||
return isNaN(result) ? result : Math.round(result);
|
||||
}
|
||||
@@ -79,6 +78,9 @@ export default class Module {
|
||||
if (!this.mods) {
|
||||
this.mods = {};
|
||||
}
|
||||
if (!this.origVals) {
|
||||
this.origVals = {};
|
||||
}
|
||||
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];
|
||||
@@ -117,7 +119,6 @@ export default class Module {
|
||||
_getModifiedValue(name) {
|
||||
const modification = Modifications.modifications[name];
|
||||
let result = this[name];
|
||||
|
||||
if (!result) {
|
||||
if (modification && modification.method === 'additive') {
|
||||
// Additive modifications start at 0 rather than NULL
|
||||
@@ -135,7 +136,7 @@ export default class Module {
|
||||
if (modification.type === 'percentage') {
|
||||
modValue = this.getModValue(name) / 10000;
|
||||
} else if (modification.type === 'numeric') {
|
||||
modValue = this.getModValue(name) / 100;
|
||||
modValue = this.getModValue(name)/ 100;
|
||||
} else {
|
||||
modValue = this.getModValue(name);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ export function standard(type, id) {
|
||||
if (!isNaN(type)) {
|
||||
type = StandardArray[type];
|
||||
}
|
||||
|
||||
let s = Modules.standard[type].find(e => e.id == id || (e.class == id.charAt(0) && e.rating == id.charAt(1)));
|
||||
if (s) {
|
||||
s = new Module({ template: s });
|
||||
@@ -196,6 +195,29 @@ export function findInternal(groupName, clss, rating, name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an internal module based on Class, Rating, Group and/or name.
|
||||
* At least one of Group name or unique module name must be provided.
|
||||
* will start searching at specified class and proceed lower until a
|
||||
* module is found or 0 is hit
|
||||
* Uses findInternal internally
|
||||
*
|
||||
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {integer} clss module Class
|
||||
* @param {String} rating module Rating
|
||||
* @param {String} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||
* @return {Object} The module if found, null if not found
|
||||
*/
|
||||
export function findMaxInternal(groupName, clss, rating, name) {
|
||||
let foundModule = null;
|
||||
let currentClss = clss;
|
||||
while (currentClss > 0 && foundModule == null) {
|
||||
foundModule = findInternal(groupName, currentClss, rating, name);
|
||||
currentClss = currentClss - 1;
|
||||
}
|
||||
return foundModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an internal Module ID based on Class, Rating, Group and/or name.
|
||||
* At least one ofGroup name or unique module name must be provided
|
||||
|
||||
@@ -490,7 +490,6 @@ export default class Ship {
|
||||
// Value passed is invalid; reset it to 0
|
||||
value = 0;
|
||||
}
|
||||
|
||||
// Handle special cases
|
||||
if (name === 'pgen') {
|
||||
// Power generation
|
||||
@@ -569,6 +568,7 @@ export default class Ship {
|
||||
// Reset Cumulative stats
|
||||
this.fuelCapacity = 0;
|
||||
this.cargoCapacity = 0;
|
||||
this.passengerCapacity = 0;
|
||||
this.ladenMass = 0;
|
||||
this.armour = this.baseArmour;
|
||||
this.shield = this.baseShieldStrength;
|
||||
@@ -616,7 +616,7 @@ export default class Ship {
|
||||
standard[i].cat = 0;
|
||||
standard[i].priority = priorities && priorities[i + 1] ? priorities[i + 1] * 1 : 0;
|
||||
standard[i].type = 'SYS';
|
||||
standard[i].m = null; // Resetting 'old' modul if there was one
|
||||
standard[i].m = null; // Resetting 'old' module if there was one
|
||||
standard[i].discountedCost = 0;
|
||||
if (comps) {
|
||||
let module = ModuleUtils.standard(i, comps.standard[i]);
|
||||
@@ -770,7 +770,7 @@ export default class Ship {
|
||||
// Alter as required due to changes in the (build) code from one version to the next
|
||||
this.upgradeInternals(internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version);
|
||||
}
|
||||
|
||||
|
||||
return this.buildWith(
|
||||
{
|
||||
bulkheads: code.charAt(0) * 1,
|
||||
@@ -1188,6 +1188,7 @@ export default class Ship {
|
||||
let unladenMass = this.hullMass;
|
||||
let cargoCapacity = 0;
|
||||
let fuelCapacity = 0;
|
||||
let passengerCapacity = 0;
|
||||
|
||||
unladenMass += this.bulkheads.m.getMass();
|
||||
|
||||
@@ -1209,6 +1210,10 @@ export default class Ship {
|
||||
fuelCapacity += slot.m.fuel;
|
||||
} else if (slot.m.grp === 'cr') {
|
||||
cargoCapacity += slot.m.cargo;
|
||||
} else if (slot.m.grp.slice(0,2) === 'pc') {
|
||||
if (slot.m.passengers) {
|
||||
passengerCapacity += slot.m.passengers;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1224,6 +1229,7 @@ export default class Ship {
|
||||
this.unladenMass = unladenMass;
|
||||
this.cargoCapacity = cargoCapacity;
|
||||
this.fuelCapacity = fuelCapacity;
|
||||
this.passengerCapacity = passengerCapacity;
|
||||
this.ladenMass = unladenMass + fuelCapacity + cargoCapacity;
|
||||
|
||||
return this;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import { canMount } from '../utils/SlotFunctions';
|
||||
import * as ModuleUtils from './ModuleUtils'
|
||||
import { canMount } from '../utils/SlotFunctions'
|
||||
|
||||
/**
|
||||
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
||||
@@ -7,20 +7,20 @@ import { canMount } from '../utils/SlotFunctions';
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames
|
||||
*/
|
||||
export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
export function multiPurpose (ship, shielded, bulkheadIndex) {
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
.useBulkhead(bulkheadIndex);
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
.useBulkhead(bulkheadIndex)
|
||||
|
||||
if (shielded) {
|
||||
ship.internal.some(function(slot) {
|
||||
ship.internal.some(function (slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, true);
|
||||
return true;
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'))
|
||||
ship.setSlotEnabled(slot, true)
|
||||
return true
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,40 +30,55 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {Object} standardOpts [Optional] Standard module optional overrides
|
||||
*/
|
||||
export function trader(ship, shielded, standardOpts) {
|
||||
let usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
// Shield generator if required
|
||||
if (shielded) {
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a,b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
break;
|
||||
export function trader (ship, shielded, standardOpts) {
|
||||
let usedSlots = []
|
||||
let bstCount = 2
|
||||
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[1], ModuleUtils.standard(1, ship.standard[1].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[4], ModuleUtils.standard(4, ship.standard[4].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
shieldInternals.some(function (slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A')
|
||||
if (shield && shield.maxmass > ship.hullMass) {
|
||||
console.log(shield)
|
||||
ship.use(slot, shield)
|
||||
ship.setSlotEnabled(slot, true)
|
||||
usedSlots.push(slot)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Fill the empty internals with cargo racks
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i];
|
||||
let slot = ship.internal[i]
|
||||
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the hardpoints
|
||||
for (let s of ship.hardpoints) {
|
||||
ship.use(s, null);
|
||||
ship.use(s, null)
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
for (let s of ship.hardpoints) {
|
||||
if (s.maxClass == 0 && bstCount) { // Mount up to 2 boosters
|
||||
ship.use(s, ModuleUtils.hardpoints('04'))
|
||||
bstCount--
|
||||
} else {
|
||||
ship.use(s, null)
|
||||
}
|
||||
}
|
||||
// ship.useLightestStandard(standardOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,127 +86,127 @@ export function trader(ship, shielded, standardOpts) {
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included
|
||||
*/
|
||||
export function explorer(ship, planetary) {
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
export function explorer (ship, planetary) {
|
||||
let standardOpts = {ppRating: 'A'},
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
|
||||
if (!planetary) { // Non-planetary explorers don't really need to boost
|
||||
standardOpts.pd = '1D';
|
||||
standardOpts.pd = '1D'
|
||||
}
|
||||
|
||||
// Cargo hatch can be disabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
|
||||
// Advanced Discovery Scanner - class 1 or higher
|
||||
const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const adsOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const adsInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a,b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a, b) => adsOrder.indexOf(a.maxClass) - adsOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < adsInternals.length; i++) {
|
||||
if (canMount(ship, adsInternals[i], 'sc')) {
|
||||
ship.use(adsInternals[i], ModuleUtils.internal('2f'));
|
||||
usedSlots.push(adsInternals[i]);
|
||||
break;
|
||||
ship.use(adsInternals[i], ModuleUtils.internal('2f'))
|
||||
usedSlots.push(adsInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (planetary) {
|
||||
// Planetary Vehicle Hangar - class 2 or higher
|
||||
const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1];
|
||||
const pvhOrder = [2, 3, 4, 5, 6, 7, 8, 1]
|
||||
const pvhInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pv)
|
||||
.sort((a,b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.pv)
|
||||
.sort((a, b) => pvhOrder.indexOf(a.maxClass) - pvhOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < pvhInternals.length; i++) {
|
||||
if (canMount(ship, pvhInternals[i], 'pv')) {
|
||||
// Planetary Vehical Hangar only has even classes
|
||||
const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass;
|
||||
ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')); // G is lower mass
|
||||
ship.setSlotEnabled(pvhInternals[i], false); // Disable power for Planetary Vehical Hangar
|
||||
usedSlots.push(pvhInternals[i]);
|
||||
break;
|
||||
const pvhClass = pvhInternals[i].maxClass % 2 === 1 ? pvhInternals[i].maxClass - 1 : pvhInternals[i].maxClass
|
||||
ship.use(pvhInternals[i], ModuleUtils.findInternal('pv', pvhClass, 'G')) // G is lower mass
|
||||
ship.setSlotEnabled(pvhInternals[i], false) // Disable power for Planetary Vehical Hangar
|
||||
usedSlots.push(pvhInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shield generator
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a,b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
sgSlot = shieldInternals[i];
|
||||
break;
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
sgSlot = shieldInternals[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Detailed Surface Scanner
|
||||
const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const dssOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const dssInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a,b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.sc)
|
||||
.sort((a, b) => dssOrder.indexOf(a.maxClass) - dssOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < dssInternals.length; i++) {
|
||||
if (canMount(ship, dssInternals[i], 'sc')) {
|
||||
ship.use(dssInternals[i], ModuleUtils.internal('2i'));
|
||||
usedSlots.push(dssInternals[i]);
|
||||
break;
|
||||
ship.use(dssInternals[i], ModuleUtils.internal('2i'))
|
||||
usedSlots.push(dssInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Fuel scoop - best possible
|
||||
const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1];
|
||||
const fuelScoopOrder = [8, 7, 6, 5, 4, 3, 2, 1]
|
||||
const fuelScoopInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.fs)
|
||||
.sort((a,b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.fs)
|
||||
.sort((a, b) => fuelScoopOrder.indexOf(a.maxClass) - fuelScoopOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < fuelScoopInternals.length; i++) {
|
||||
if (canMount(ship, fuelScoopInternals[i], 'fs')) {
|
||||
ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'));
|
||||
usedSlots.push(fuelScoopInternals[i]);
|
||||
fuelScoopSlot = fuelScoopInternals[i];
|
||||
break;
|
||||
ship.use(fuelScoopInternals[i], ModuleUtils.findInternal('fs', fuelScoopInternals[i].maxClass, 'A'))
|
||||
usedSlots.push(fuelScoopInternals[i])
|
||||
fuelScoopSlot = fuelScoopInternals[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// AFMUs - fill as they are 0-weight
|
||||
const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1];
|
||||
const afmuOrder = [8, 7, 6, 5, 4, 3, 2, 1]
|
||||
const afmuInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a,b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a, b) => afmuOrder.indexOf(a.maxClass) - afmuOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < afmuInternals.length; i++) {
|
||||
if (canMount(ship, afmuInternals[i], 'am')) {
|
||||
ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'));
|
||||
usedSlots.push(afmuInternals[i]);
|
||||
ship.setSlotEnabled(afmuInternals[i], false); // Disable power for AFM Unit
|
||||
ship.use(afmuInternals[i], ModuleUtils.findInternal('am', afmuInternals[i].maxClass, 'A'))
|
||||
usedSlots.push(afmuInternals[i])
|
||||
ship.setSlotEnabled(afmuInternals[i], false) // Disable power for AFM Unit
|
||||
}
|
||||
}
|
||||
|
||||
for (let s of ship.hardpoints) {
|
||||
if (s.maxClass == 0 && heatSinkCount) { // Mount up to 2 heatsinks
|
||||
ship.use(s, ModuleUtils.hardpoints('02'));
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2); // Only enable a single Heatsink
|
||||
heatSinkCount--;
|
||||
ship.use(s, ModuleUtils.hardpoints('02'))
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2) // Only enable a single Heatsink
|
||||
heatSinkCount--
|
||||
} else {
|
||||
ship.use(s, null);
|
||||
ship.use(s, null)
|
||||
}
|
||||
}
|
||||
|
||||
if (sgSlot && fuelScoopSlot) {
|
||||
// The SG and Fuel scoop to not need to be powered at the same time
|
||||
if (sgSlot.m.getPowerUsage() > fuelScoopSlot.m.getPowerUsage()) { // The Shield generator uses the most power
|
||||
ship.setSlotEnabled(fuelScoopSlot, false);
|
||||
ship.setSlotEnabled(fuelScoopSlot, false)
|
||||
} else { // The Fuel scoop uses the most power
|
||||
ship.setSlotEnabled(sgSlot, false);
|
||||
ship.setSlotEnabled(sgSlot, false)
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
ship.useLightestStandard(standardOpts)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,187 +214,188 @@ export function explorer(ship, planetary) {
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
*/
|
||||
export function miner(ship, shielded) {
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
export function miner (ship, shielded) {
|
||||
shielded = true
|
||||
let standardOpts = {ppRating: 'A'},
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
|
||||
// Cargo hatch should be enabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, true);
|
||||
ship.setSlotEnabled(ship.cargoHatch, true)
|
||||
|
||||
// Largest possible refinery
|
||||
const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1];
|
||||
const refineryOrder = [4, 5, 6, 7, 8, 3, 2, 1]
|
||||
const refineryInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.rf)
|
||||
.sort((a,b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.rf)
|
||||
.sort((a, b) => refineryOrder.indexOf(a.maxClass) - refineryOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < refineryInternals.length; i++) {
|
||||
if (canMount(ship, refineryInternals[i], 'rf')) {
|
||||
ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'));
|
||||
usedSlots.push(refineryInternals[i]);
|
||||
break;
|
||||
ship.use(refineryInternals[i], ModuleUtils.findInternal('rf', Math.min(refineryInternals[i].maxClass, 4), 'A'))
|
||||
usedSlots.push(refineryInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Prospector limpet controller - 3A if possible
|
||||
const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1];
|
||||
const prospectorOrder = [3, 4, 5, 6, 7, 8, 2, 1]
|
||||
const prospectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a,b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.pc)
|
||||
.sort((a, b) => prospectorOrder.indexOf(a.maxClass) - prospectorOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < prospectorInternals.length; i++) {
|
||||
if (canMount(ship, prospectorInternals[i], 'pc')) {
|
||||
// Prospector only has odd classes
|
||||
const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass;
|
||||
ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'));
|
||||
usedSlots.push(prospectorInternals[i]);
|
||||
break;
|
||||
const prospectorClass = prospectorInternals[i].maxClass % 2 === 0 ? prospectorInternals[i].maxClass - 1 : prospectorInternals[i].maxClass
|
||||
ship.use(prospectorInternals[i], ModuleUtils.findInternal('pc', prospectorClass, 'A'))
|
||||
usedSlots.push(prospectorInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Shield generator if required
|
||||
if (shielded) {
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a,b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
break;
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dual mining lasers of highest possible class; remove anything else
|
||||
const miningLaserOrder = [2, 3, 4, 1, 0];
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function(a,b) {
|
||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
|
||||
});
|
||||
const miningLaserOrder = [2, 3, 4, 1, 0]
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function (a, b) {
|
||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass)
|
||||
})
|
||||
for (let s of miningLaserHardpoints) {
|
||||
if (s.maxClass >= 1 && miningLaserCount) {
|
||||
ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'));
|
||||
miningLaserCount--;
|
||||
ship.use(s, ModuleUtils.hardpoints(s.maxClass >= 2 ? '2m' : '2l'))
|
||||
miningLaserCount--
|
||||
} else {
|
||||
ship.use(s, null);
|
||||
ship.use(s, null)
|
||||
}
|
||||
}
|
||||
|
||||
// Number of collector limpets required to be active is a function of the size of the ship and the power of the lasers
|
||||
const miningLaserDps = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getDps();
|
||||
}, 0);
|
||||
.reduce(function (a, b) {
|
||||
return a + b.m.getDps()
|
||||
}, 0)
|
||||
// Find out how many internal slots we have, and their potential cargo size
|
||||
const potentialCargo = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.cr)
|
||||
.map(b => Math.pow(2, b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.cr)
|
||||
.map(b => Math.pow(2, b.maxClass))
|
||||
// One collector for each 1.25 DPS, multiply by 1.25 for medium ships and 1.5 for large ships as they have further to travel
|
||||
// 0 if we only have 1 cargo slot, otherwise minium of 1 and maximum of 6 (excluding size modifier)
|
||||
const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1;
|
||||
let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)));
|
||||
|
||||
const sizeModifier = ship.class == 2 ? 1.2 : ship.class == 3 ? 1.5 : 1
|
||||
let collectorLimpetsRequired = potentialCargo.length == 1 ? 0 : Math.ceil(sizeModifier * Math.min(6, Math.floor(miningLaserDps / 1.25)))
|
||||
|
||||
if (collectorLimpetsRequired > 0) {
|
||||
const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const collectorOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const collectorInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.cc)
|
||||
.sort((a,b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.cc)
|
||||
.sort((a, b) => collectorOrder.indexOf(a.maxClass) - collectorOrder.indexOf(b.maxClass))
|
||||
// Always keep at least 2 slots free for cargo racks (1 for shielded)
|
||||
for (let i = 0; i < collectorInternals.length - (shielded ? 1 : 2) && collectorLimpetsRequired > 0; i++) {
|
||||
if (canMount(ship, collectorInternals[i], 'cc')) {
|
||||
// Collector only has odd classes
|
||||
const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass;
|
||||
ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'));
|
||||
usedSlots.push(collectorInternals[i]);
|
||||
collectorLimpetsRequired -= collectorInternals[i].m.maximum;
|
||||
const collectorClass = collectorInternals[i].maxClass % 2 === 0 ? collectorInternals[i].maxClass - 1 : collectorInternals[i].maxClass
|
||||
ship.use(collectorInternals[i], ModuleUtils.findInternal('cc', collectorClass, 'D'))
|
||||
usedSlots.push(collectorInternals[i])
|
||||
collectorLimpetsRequired -= collectorInternals[i].m.maximum
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Power distributor to power the mining lasers indefinitely
|
||||
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getEps();
|
||||
}, 0);
|
||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
|
||||
.reduce(function (a, b) {
|
||||
return a + b.m.getEps()
|
||||
}, 0)
|
||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({weprate: wepRateRequired}).id
|
||||
|
||||
// Fill the empty internals with cargo racks
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i];
|
||||
let slot = ship.internal[i]
|
||||
if (usedSlots.indexOf(slot) == -1 && canMount(ship, slot, 'cr')) {
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'))
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
ship.useLightestStandard(standardOpts)
|
||||
}
|
||||
|
||||
/**
|
||||
* Racer Role
|
||||
* @param {Ship} ship Ship instance
|
||||
*/
|
||||
export function racer(ship) {
|
||||
export function racer (ship) {
|
||||
let standardOpts = {},
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass)
|
||||
|
||||
// Cargo hatch can be disabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
|
||||
// Shield generator
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
const shieldInternals = ship.internal.filter(a => usedSlots.indexOf(a) == -1)
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a,b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass))
|
||||
for (let i = 0; i < shieldInternals.length; i++) {
|
||||
if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
ship.use(shieldInternals[i], sg);
|
||||
usedSlots.push(shieldInternals[i]);
|
||||
sgSlot = shieldInternals[i];
|
||||
break;
|
||||
ship.use(shieldInternals[i], sg)
|
||||
usedSlots.push(shieldInternals[i])
|
||||
sgSlot = shieldInternals[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the hardpoints
|
||||
for (let s of ship.hardpoints) {
|
||||
ship.use(s, null);
|
||||
ship.use(s, null)
|
||||
}
|
||||
|
||||
// Empty the internals
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i];
|
||||
let slot = ship.internal[i]
|
||||
if (usedSlots.indexOf(slot) == -1) {
|
||||
ship.use(slot, null);
|
||||
ship.use(slot, null)
|
||||
}
|
||||
}
|
||||
|
||||
// Best thrusters
|
||||
if (ship.standard[1].maxClass === 3) {
|
||||
standardOpts.th = 'tz';
|
||||
standardOpts.th = 'tz'
|
||||
} else if (ship.standard[1].maxClass === 2) {
|
||||
standardOpts.th = 'u0';
|
||||
standardOpts.th = 'u0'
|
||||
} else {
|
||||
standardOpts.th = ship.standard[1].maxClass + 'A';
|
||||
standardOpts.th = ship.standard[1].maxClass + 'A'
|
||||
}
|
||||
|
||||
// Best power distributor for more boosting
|
||||
standardOpts.pd = ship.standard[4].maxClass + 'A';
|
||||
standardOpts.pd = ship.standard[4].maxClass + 'A'
|
||||
|
||||
// Smallest possible FSD drive
|
||||
standardOpts.fsd = '2D';
|
||||
standardOpts.fsd = '2D'
|
||||
// Minimal fuel tank
|
||||
standardOpts.ft = '1C';
|
||||
standardOpts.ft = '1C'
|
||||
|
||||
// Disable nearly everything
|
||||
standardOpts.fsdDisabled = true;
|
||||
standardOpts.sDisabled = true;
|
||||
standardOpts.pdDisabled = true;
|
||||
standardOpts.lsDisabled = true;
|
||||
standardOpts.fsdDisabled = true
|
||||
standardOpts.sDisabled = true
|
||||
standardOpts.pdDisabled = true
|
||||
standardOpts.lsDisabled = true
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
ship.useLightestStandard(standardOpts)
|
||||
|
||||
// Apply engineering to each module
|
||||
// ship.standard[1].m.blueprint = getBlueprint('Engine_Dirty', ship.standard[0]);
|
||||
|
||||
@@ -12,6 +12,9 @@ import { Modifications } from 'coriolis-data/dist';
|
||||
*/
|
||||
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
||||
const effects = [];
|
||||
if (!blueprint || !blueprint.features) {
|
||||
return undefined;
|
||||
}
|
||||
for (const feature in blueprint.features) {
|
||||
const featureIsBeneficial = isBeneficial(feature, blueprint.features[feature]);
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
@@ -225,27 +228,13 @@ export function isValueBeneficial(feature, value) {
|
||||
*/
|
||||
export function getBlueprint(name, module) {
|
||||
// Start with a copy of the blueprint
|
||||
const blueprint = JSON.parse(JSON.stringify(Modifications.blueprints[name]));
|
||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
|
||||
const found = Modifications.blueprints[findMod(name)];
|
||||
if (!found || !found.fdname) {
|
||||
return {};
|
||||
}
|
||||
const blueprint = JSON.parse(JSON.stringify(found));
|
||||
if (module) {
|
||||
if (module.grp === 'bh' || module.grp === 'hr' || module.grp === 'sg' || module.grp === 'psg' || module.grp === 'bsg') {
|
||||
// Bulkheads, hull reinforcements and shield generators need to have their resistances altered by the base values
|
||||
for (const grade in blueprint.grades) {
|
||||
for (const feature in blueprint.grades[grade].features) {
|
||||
if (feature === 'explres') {
|
||||
blueprint.grades[grade].features[feature][0] *= (1 - module.explres);
|
||||
blueprint.grades[grade].features[feature][1] *= (1 - module.explres);
|
||||
}
|
||||
if (feature === 'kinres') {
|
||||
blueprint.grades[grade].features[feature][0] *= (1 - module.kinres);
|
||||
blueprint.grades[grade].features[feature][1] *= (1 - module.kinres);
|
||||
}
|
||||
if (feature === 'thermres') {
|
||||
blueprint.grades[grade].features[feature][0] *= (1 - module.thermres);
|
||||
blueprint.grades[grade].features[feature][1] *= (1 - module.thermres);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (module.grp === 'sb') {
|
||||
// Shield boosters are treated internally as straight modifiers, so rather than (for example)
|
||||
// being a 4% boost they are a 104% multiplier. We need to fix the values here so that they look
|
||||
@@ -267,57 +256,19 @@ export function getBlueprint(name, module) {
|
||||
* Provide 'worst' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
* @param {Number} percent The percent to set values to of full.
|
||||
*/
|
||||
export function setWorst(ship, m) {
|
||||
ship.clearModifications(m);
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
const value = features[featureName][0];
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'best' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
*/
|
||||
export function setBest(ship, m) {
|
||||
export function setPercent(ship, m, percent) {
|
||||
ship.clearModifications(m);
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
const value = features[featureName][1];
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'extreme' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
*/
|
||||
export function setExtreme(ship, m) {
|
||||
ship.clearModifications(m);
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
let value;
|
||||
if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][0];
|
||||
} else {
|
||||
value = features[featureName][1];
|
||||
}
|
||||
const featureIsBeneficial = isBeneficial(featureName, features[featureName]);
|
||||
if (featureIsBeneficial === true) {
|
||||
_setValue(ship, m, featureName, (percent / 100) * value);
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][1];
|
||||
} else {
|
||||
value = features[featureName][0];
|
||||
}
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,15 @@ const SHIP_FD_NAME_TO_CORIOLIS_NAME = {
|
||||
'Type6': 'type_6_transporter',
|
||||
'Type7': 'type_7_transport',
|
||||
'Type9': 'type_9_heavy',
|
||||
'Type9_Military': 'type_10_defender',
|
||||
'TypeX': 'alliance_chieftain',
|
||||
'Viper': 'viper',
|
||||
'Viper_MkIV': 'viper_mk_iv',
|
||||
'Vulture': 'vulture'
|
||||
};
|
||||
|
||||
// Mapping from hardpoint class to name in companion API
|
||||
const HARDPOINT_NUM_TO_CLASS = {
|
||||
export const HARDPOINT_NUM_TO_CLASS = {
|
||||
0: 'Tiny',
|
||||
1: 'Small',
|
||||
2: 'Medium',
|
||||
@@ -104,7 +106,7 @@ function _moduleFromEdId(edId) {
|
||||
* @return {string} the Coriolis model of the ship
|
||||
*/
|
||||
function _shipModelFromEDName(edName) {
|
||||
return SHIP_FD_NAME_TO_CORIOLIS_NAME[edName];
|
||||
return SHIP_FD_NAME_TO_CORIOLIS_NAME[Object.keys(SHIP_FD_NAME_TO_CORIOLIS_NAME).find(elem => elem.toLowerCase() === edName.toLowerCase())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +115,7 @@ function _shipModelFromEDName(edName) {
|
||||
* @return {string} the Coriolis model of the ship
|
||||
*/
|
||||
export function shipModelFromJson(json) {
|
||||
return _shipModelFromEDName(json.name);
|
||||
return _shipModelFromEDName(json.name || json.Ship);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,30 +143,34 @@ export function shipFromJson(json) {
|
||||
ship.cargoHatch.enabled = false;
|
||||
ship.cargoHatch.priority = 4;
|
||||
}
|
||||
|
||||
|
||||
let rootModule;
|
||||
|
||||
// Add the bulkheads
|
||||
const armourJson = json.modules.Armour.module;
|
||||
if (armourJson.name.endsWith('_Armour_Grade1')) {
|
||||
if (armourJson.name.toLowerCase().endsWith('_armour_grade1')) {
|
||||
ship.useBulkhead(0, true);
|
||||
} else if (armourJson.name.endsWith('_Armour_Grade2')) {
|
||||
} else if (armourJson.name.toLowerCase().endsWith('_armour_grade2')) {
|
||||
ship.useBulkhead(1, true);
|
||||
} else if (armourJson.name.endsWith('_Armour_Grade3')) {
|
||||
} else if (armourJson.name.toLowerCase().endsWith('_armour_grade3')) {
|
||||
ship.useBulkhead(2, true);
|
||||
} else if (armourJson.name.endsWith('_Armour_Mirrored')) {
|
||||
} else if (armourJson.name.toLowerCase().endsWith('_armour_mirrored')) {
|
||||
ship.useBulkhead(3, true);
|
||||
} else if (armourJson.name.endsWith('_Armour_Reactive')) {
|
||||
} else if (armourJson.name.toLowerCase().endsWith('_armour_reactive')) {
|
||||
ship.useBulkhead(4, true);
|
||||
} else {
|
||||
throw 'Unknown bulkheads "' + armourJson.name + '"';
|
||||
}
|
||||
ship.bulkheads.enabled = true;
|
||||
if (armourJson.modifiers) _addModifications(ship.bulkheads.m, armourJson.modifiers, armourJson.recipeName, armourJson.recipeLevel);
|
||||
rootModule = json.modules.Armour;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(ship.bulkheads.m, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
|
||||
// Add the standard modules
|
||||
// Power plant
|
||||
const powerplantJson = json.modules.PowerPlant.module;
|
||||
const powerplant = _moduleFromEdId(powerplantJson.id);
|
||||
if (powerplantJson.modifiers) _addModifications(powerplant, powerplantJson.modifiers, powerplantJson.recipeName, powerplantJson.recipeLevel);
|
||||
rootModule = json.modules.PowerPlant;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(powerplant, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[0], powerplant, true);
|
||||
ship.standard[0].enabled = powerplantJson.on === true;
|
||||
ship.standard[0].priority = powerplantJson.priority;
|
||||
@@ -172,7 +178,8 @@ export function shipFromJson(json) {
|
||||
// Thrusters
|
||||
const thrustersJson = json.modules.MainEngines.module;
|
||||
const thrusters = _moduleFromEdId(thrustersJson.id);
|
||||
if (thrustersJson.modifiers) _addModifications(thrusters, thrustersJson.modifiers, thrustersJson.recipeName, thrustersJson.recipeLevel);
|
||||
rootModule = json.modules.MainEngines;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(thrusters, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[1], thrusters, true);
|
||||
ship.standard[1].enabled = thrustersJson.on === true;
|
||||
ship.standard[1].priority = thrustersJson.priority;
|
||||
@@ -180,7 +187,8 @@ export function shipFromJson(json) {
|
||||
// FSD
|
||||
const frameshiftdriveJson = json.modules.FrameShiftDrive.module;
|
||||
const frameshiftdrive = _moduleFromEdId(frameshiftdriveJson.id);
|
||||
if (frameshiftdriveJson.modifiers) _addModifications(frameshiftdrive, frameshiftdriveJson.modifiers, frameshiftdriveJson.recipeName, frameshiftdriveJson.recipeLevel);
|
||||
rootModule = json.modules.FrameShiftDrive;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(frameshiftdrive, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[2], frameshiftdrive, true);
|
||||
ship.standard[2].enabled = frameshiftdriveJson.on === true;
|
||||
ship.standard[2].priority = frameshiftdriveJson.priority;
|
||||
@@ -188,7 +196,8 @@ export function shipFromJson(json) {
|
||||
// Life support
|
||||
const lifesupportJson = json.modules.LifeSupport.module;
|
||||
const lifesupport = _moduleFromEdId(lifesupportJson.id);
|
||||
if (lifesupportJson.modifiers)_addModifications(lifesupport, lifesupportJson.modifiers, lifesupportJson.recipeName, lifesupportJson.recipeLevel);
|
||||
rootModule = json.modules.LifeSupport;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(lifesupport, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[3], lifesupport, true);
|
||||
ship.standard[3].enabled = lifesupportJson.on === true;
|
||||
ship.standard[3].priority = lifesupportJson.priority;
|
||||
@@ -196,7 +205,8 @@ export function shipFromJson(json) {
|
||||
// Power distributor
|
||||
const powerdistributorJson = json.modules.PowerDistributor.module;
|
||||
const powerdistributor = _moduleFromEdId(powerdistributorJson.id);
|
||||
if (powerdistributorJson.modifiers) _addModifications(powerdistributor, powerdistributorJson.modifiers, powerdistributorJson.recipeName, powerdistributorJson.recipeLevel);
|
||||
rootModule = json.modules.PowerDistributor;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(powerdistributor, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[4], powerdistributor, true);
|
||||
ship.standard[4].enabled = powerdistributorJson.on === true;
|
||||
ship.standard[4].priority = powerdistributorJson.priority;
|
||||
@@ -204,7 +214,8 @@ export function shipFromJson(json) {
|
||||
// Sensors
|
||||
const sensorsJson = json.modules.Radar.module;
|
||||
const sensors = _moduleFromEdId(sensorsJson.id);
|
||||
if (sensorsJson.modifiers) _addModifications(sensors, sensorsJson.modifiers, sensorsJson.recipeName, sensorsJson.recipeLevel);
|
||||
rootModule = json.modules.Radar;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(sensors, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.standard[5], sensors, true);
|
||||
ship.standard[5].enabled = sensorsJson.on === true;
|
||||
ship.standard[5].priority = sensorsJson.priority;
|
||||
@@ -240,7 +251,8 @@ export function shipFromJson(json) {
|
||||
} else {
|
||||
const hardpointJson = hardpointSlot.module;
|
||||
const hardpoint = _moduleFromEdId(hardpointJson.id);
|
||||
if (hardpointJson.modifiers) _addModifications(hardpoint, hardpointJson.modifiers, hardpointJson.recipeName, hardpointJson.recipeLevel);
|
||||
rootModule = hardpointSlot;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(hardpoint, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel, rootModule.specialModifications);
|
||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointJson.on === true;
|
||||
ship.hardpoints[hardpointArrayNum].priority = hardpointJson.priority;
|
||||
@@ -282,7 +294,8 @@ export function shipFromJson(json) {
|
||||
} else {
|
||||
const internalJson = internalSlot.module;
|
||||
const internal = _moduleFromEdId(internalJson.id);
|
||||
if (internalJson.modifiers) _addModifications(internal, internalJson.modifiers, internalJson.recipeName, internalJson.recipeLevel);
|
||||
rootModule = internalSlot;
|
||||
if (rootModule.WorkInProgress_modifications) _addModifications(internal, rootModule.WorkInProgress_modifications, rootModule.engineer.recipeName, rootModule.engineer.recipeLevel);
|
||||
ship.use(ship.internal[i], internal, true);
|
||||
ship.internal[i].enabled = internalJson.on === true;
|
||||
ship.internal[i].priority = internalJson.priority;
|
||||
@@ -299,35 +312,48 @@ export function shipFromJson(json) {
|
||||
* @param {Object} modifiers the modifiers
|
||||
* @param {Object} blueprint the blueprint of the modification
|
||||
* @param {Object} grade the grade of the modification
|
||||
* @param {Object} specialModifications special modification
|
||||
*/
|
||||
function _addModifications(module, modifiers, blueprint, grade) {
|
||||
if (!modifiers || !modifiers.modifiers) return;
|
||||
|
||||
function _addModifications(module, modifiers, blueprint, grade, specialModifications) {
|
||||
if (!modifiers) return;
|
||||
let special;
|
||||
for (const i in modifiers.modifiers) {
|
||||
if (specialModifications) {
|
||||
special = Modifications.specials[Object.keys(specialModifications)[0]]
|
||||
}
|
||||
for (const i in modifiers) {
|
||||
// Some special modifications
|
||||
if (modifiers.modifiers[i].name === 'mod_weapon_clip_size_override') {
|
||||
if (modifiers[i].name === 'mod_weapon_clip_size_override') {
|
||||
// This is a numeric addition to the clip size, but we need to work it out in terms of being a percentage so
|
||||
// that it works the same as other modifications
|
||||
const origClip = module.clip || 1;
|
||||
module.setModValue('clip', ((modifiers.modifiers[i].value - origClip) / origClip) * 10000);
|
||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_size') {
|
||||
module.setModValue('clip', ((modifiers[i].value - origClip) / origClip) * 10000);
|
||||
} else if (modifiers[i].name === 'mod_weapon_burst_size') {
|
||||
// This is an absolute number that acts as an override
|
||||
module.setModValue('burst', modifiers.modifiers[i].value * 100);
|
||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_rof') {
|
||||
module.setModValue('burst', modifiers[i].value * 100);
|
||||
} else if (modifiers[i].name === 'mod_weapon_burst_rof') {
|
||||
// This is an absolute number that acts as an override
|
||||
module.setModValue('burstrof', modifiers.modifiers[i].value * 100);
|
||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_falloffrange_from_range') {
|
||||
module.setModValue('burstrof', modifiers[i].value * 100);
|
||||
} else if (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_')) {
|
||||
} else if (modifiers[i].name && 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];
|
||||
special = Modifications.specials[modifiers[i].name];
|
||||
} else {
|
||||
// Look up the modifiers to find what we need to do
|
||||
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
||||
const value = modifiers.modifiers[i].value;
|
||||
|
||||
const modifierActions = Modifications.modifierActions[i];
|
||||
let value;
|
||||
if (i === 'OutfittingFieldType_DefenceModifierShieldMultiplier') {
|
||||
value = modifiers[i].value - 1;
|
||||
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier' && blueprint.startsWith('Armour_')) {
|
||||
value = (modifiers[i].value - module.hullboost) / module.hullboost;
|
||||
} else if (i === 'OutfittingFieldType_DefenceModifierHealthMultiplier') {
|
||||
value = modifiers[i].value / module.hullboost;
|
||||
} else if (i === 'OutfittingFieldType_RateOfFire') {
|
||||
value = (1 / Math.abs(modifiers[i].value));
|
||||
} else {
|
||||
value = modifiers[i].value - 1;
|
||||
}
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
if (isNaN(modifierActions[action])) {
|
||||
@@ -354,7 +380,7 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
||||
module.blueprint.special = special;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Need to fix up a few items
|
||||
|
||||
// Shield boosters are treated internally as straight modifiers, so rather than (for example)
|
||||
@@ -377,7 +403,7 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
||||
module.setModValue('thermres', ((module.getModValue('thermres') / 10000) * -1) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Shield generator resistance is actually a damage modifier, so needs to be inverted.
|
||||
// In addition, the modification is based off the inherent resistance of the module
|
||||
if (ModuleUtils.isShieldGenerator(module.grp)) {
|
||||
@@ -405,7 +431,7 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
||||
module.setModValue('thermres', ((1 - (1 - module.thermres) * (1 + module.getModValue('thermres') / 10000)) - module.thermres) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Bulkhead resistance is actually a damage modifier, so needs to be inverted.
|
||||
// In addition, the modification is based off the inherent resistance of the module
|
||||
if (module.grp == 'bh') {
|
||||
@@ -423,7 +449,7 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
||||
// Bulkhead boost is based off the inherent boost of the module
|
||||
if (module.grp == 'bh') {
|
||||
const alteredBoost = (1 + module.hullboost) * (1 + module.getModValue('hullboost') / 10000) - 1;
|
||||
module.setModValue('hullboost', (alteredBoost / module.hullboost - 1) * 10000);
|
||||
module.setModValue('hullboost', (alteredBoost / module.hullboost - 1) * 1000);
|
||||
}
|
||||
|
||||
// Jitter is an absolute number, so we need to divide it by 100
|
||||
@@ -431,11 +457,6 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
||||
module.setModValue('jitter', module.getModValue('jitter') / 100);
|
||||
}
|
||||
|
||||
// FD uses interval between bursts internally, so we need to translate this to a real rate of fire
|
||||
if (module.getModValue('rof')) {
|
||||
module.setModValue('rof', ((1 / (1 + module.getModValue('rof') / 10000)) - 1) * 10000);
|
||||
}
|
||||
|
||||
// Clip size is rounded up so that the result is a whole number
|
||||
if (module.getModValue('clip')) {
|
||||
const individual = 1 / (module.clip || 1);
|
||||
|
||||
292
src/app/utils/JournalUtils.js
Normal file
292
src/app/utils/JournalUtils.js
Normal file
@@ -0,0 +1,292 @@
|
||||
import Ship from '../shipyard/Ship'
|
||||
import { HARDPOINT_NUM_TO_CLASS, shipModelFromJson } from './CompanionApiUtils'
|
||||
import { Ships } from 'coriolis-data/dist'
|
||||
import Module from '../shipyard/Module'
|
||||
import { Modules } from 'coriolis-data/dist'
|
||||
import { Modifications } from 'coriolis-data/dist'
|
||||
import { getBlueprint } from './BlueprintFunctions'
|
||||
|
||||
/**
|
||||
* Obtain a module given its FD Name
|
||||
* @param {string} fdname the FD Name of the module
|
||||
* @return {Module} the module
|
||||
*/
|
||||
function _moduleFromFdName (fdname) {
|
||||
if (!fdname) return null
|
||||
fdname = fdname.toLowerCase()
|
||||
// Check standard modules
|
||||
for (const grp in Modules.standard) {
|
||||
if (Modules.standard.hasOwnProperty(grp)) {
|
||||
for (const i in Modules.standard[grp]) {
|
||||
if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.standard[grp][i]})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check hardpoint modules
|
||||
for (const grp in Modules.hardpoints) {
|
||||
if (Modules.hardpoints.hasOwnProperty(grp)) {
|
||||
for (const i in Modules.hardpoints[grp]) {
|
||||
if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.hardpoints[grp][i]})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check internal modules
|
||||
for (const grp in Modules.internal) {
|
||||
if (Modules.internal.hasOwnProperty(grp)) {
|
||||
for (const i in Modules.internal[grp]) {
|
||||
if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) {
|
||||
// Found it
|
||||
return new Module({template: Modules.internal[grp][i]})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ship from the journal Loadout event JSON
|
||||
* @param {object} json the Loadout event JSON
|
||||
* @return {Ship} the built ship
|
||||
*/
|
||||
export function shipFromLoadoutJSON (json) {
|
||||
// Start off building a basic ship
|
||||
const shipModel = shipModelFromJson(json)
|
||||
if (!shipModel) {
|
||||
throw 'No such ship found: "' + json.Ship + '"'
|
||||
}
|
||||
const shipTemplate = Ships[shipModel]
|
||||
|
||||
let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots)
|
||||
ship.buildWith(null)
|
||||
// Initial Ship building, don't do engineering yet.
|
||||
let opts = [];
|
||||
|
||||
for (const module of json.Modules) {
|
||||
switch (module.Slot) {
|
||||
// Cargo Hatch.
|
||||
case 'CargoHatch':
|
||||
ship.cargoHatch.enabled = module.On
|
||||
ship.cargoHatch.priority = module.Priority
|
||||
break
|
||||
// Add the bulkheads
|
||||
case 'Armour':
|
||||
if (module.Item.toLowerCase().endsWith('_armour_grade1')) {
|
||||
ship.useBulkhead(0, true)
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_grade2')) {
|
||||
ship.useBulkhead(1, true)
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_grade3')) {
|
||||
ship.useBulkhead(2, true)
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) {
|
||||
ship.useBulkhead(3, true)
|
||||
} else if (module.Item.toLowerCase().endsWith('_armour_reactive')) {
|
||||
ship.useBulkhead(4, true)
|
||||
} else {
|
||||
throw 'Unknown bulkheads "' + module.Item + '"'
|
||||
}
|
||||
ship.bulkheads.enabled = true
|
||||
if (module.Engineering) _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'PowerPlant':
|
||||
const powerplant = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[0], powerplant, true)
|
||||
ship.standard[0].enabled = module.On
|
||||
ship.standard[0].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'MainEngines':
|
||||
const thrusters = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[1], thrusters, true)
|
||||
ship.standard[1].enabled = module.On
|
||||
ship.standard[1].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'FrameShiftDrive':
|
||||
const frameshiftdrive = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[2], frameshiftdrive, true)
|
||||
ship.standard[2].enabled = module.On
|
||||
ship.standard[2].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'LifeSupport':
|
||||
const lifesupport = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[3], lifesupport, true)
|
||||
ship.standard[3].enabled = module.On === true
|
||||
ship.standard[3].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'PowerDistributor':
|
||||
const powerdistributor = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[4], powerdistributor, true)
|
||||
ship.standard[4].enabled = module.On
|
||||
ship.standard[4].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'Radar':
|
||||
const sensors = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[5], sensors, true)
|
||||
ship.standard[5].enabled = module.On
|
||||
ship.standard[5].priority = module.Priority
|
||||
if (module.Engineering) _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
|
||||
break
|
||||
case 'FuelTank':
|
||||
const fueltank = _moduleFromFdName(module.Item)
|
||||
ship.use(ship.standard[6], fueltank, true)
|
||||
ship.standard[6].enabled = true
|
||||
ship.standard[6].priority = 0
|
||||
break
|
||||
default:
|
||||
}
|
||||
for (const module of json.Modules) {
|
||||
if (module.Slot.search(/Hardpoint/) !== -1) {
|
||||
// Add hardpoints
|
||||
let hardpoint;
|
||||
let hardpointClassNum = -1
|
||||
let hardpointSlotNum = -1
|
||||
let hardpointArrayNum = 0
|
||||
for (let i in shipTemplate.slots.hardpoints) {
|
||||
if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
|
||||
// Another slot of the same class
|
||||
hardpointSlotNum++
|
||||
} else {
|
||||
// The first slot of a new class
|
||||
hardpointClassNum = shipTemplate.slots.hardpoints[i]
|
||||
hardpointSlotNum = 1
|
||||
}
|
||||
|
||||
// Now that we know what we're looking for, find it
|
||||
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum
|
||||
const hardpointSlot = json.Modules.find(elem => elem.Slot === hardpointName)
|
||||
if (!hardpointSlot) {
|
||||
// This can happen with old imports that don't contain new hardpoints
|
||||
} else if (!hardpointSlot) {
|
||||
// No module
|
||||
} else {
|
||||
hardpoint = _moduleFromFdName(hardpointSlot.Item)
|
||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true)
|
||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On
|
||||
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority
|
||||
opts.push({coriolisMod: hardpoint, json: hardpointSlot});
|
||||
}
|
||||
hardpointArrayNum++
|
||||
}
|
||||
}
|
||||
if (module.Slot.search(/Slot\d/) !== -1) {
|
||||
let internalSlotNum = 1
|
||||
let militarySlotNum = 1
|
||||
for (let i in shipTemplate.slots.internal) {
|
||||
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'Military' : false
|
||||
|
||||
// The internal slot might be a standard or a military slot. Military slots have a different naming system
|
||||
let internalSlot = null
|
||||
if (isMilitary) {
|
||||
const internalName = 'Military0' + militarySlotNum
|
||||
internalSlot = json.Modules.find(elem => elem.Slot === internalName)
|
||||
militarySlotNum++
|
||||
} else {
|
||||
// Slot numbers are not contiguous so handle skips.
|
||||
while (internalSlot === null && internalSlotNum < 99) {
|
||||
// Slot sizes have no relationship to the actual size, either, so check all possibilities
|
||||
for (let slotsize = 0; slotsize < 9; slotsize++) {
|
||||
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize
|
||||
if (json.Modules.find(elem => elem.Slot === internalName)) {
|
||||
internalSlot = json.Modules.find(elem => elem.Slot === internalName);
|
||||
break
|
||||
}
|
||||
}
|
||||
internalSlotNum++
|
||||
}
|
||||
}
|
||||
|
||||
if (!internalSlot) {
|
||||
// This can happen with old imports that don't contain new slots
|
||||
} else if (!internalSlot) {
|
||||
// No module
|
||||
} else {
|
||||
const internalJson = internalSlot
|
||||
const internal = _moduleFromFdName(internalJson.Item)
|
||||
ship.use(ship.internal[i], internal, true)
|
||||
ship.internal[i].enabled = internalJson.On === true
|
||||
ship.internal[i].priority = internalJson.Priority
|
||||
opts.push({coriolisMod: internal, json: internalSlot});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const i of opts) {
|
||||
if (i.json.Engineering) _addModifications(i.coriolisMod, i.json.Engineering.Modifiers, i.json.Engineering.BlueprintName, i.json.Engineering.Level, i.json.Engineering.ExperimentalEffect)
|
||||
}
|
||||
// We don't have any information on it so guess it's priority 5 and disabled
|
||||
if (!ship.cargoHatch) {
|
||||
ship.cargoHatch.enabled = false
|
||||
ship.cargoHatch.priority = 4
|
||||
}
|
||||
console.log(ship)
|
||||
|
||||
// Now update the ship's codes before returning it
|
||||
return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the modifications for a module
|
||||
* @param {Module} module the module
|
||||
* @param {Object} modifiers the modifiers
|
||||
* @param {Object} blueprint the blueprint of the modification
|
||||
* @param {Object} grade the grade of the modification
|
||||
* @param {Object} specialModifications special modification
|
||||
*/
|
||||
function _addModifications (module, modifiers, blueprint, grade, specialModifications) {
|
||||
if (!modifiers) return
|
||||
let special
|
||||
if (specialModifications) {
|
||||
special = Modifications.specials[specialModifications]
|
||||
}
|
||||
for (const i in modifiers) {
|
||||
// Some special modifications
|
||||
// Look up the modifiers to find what we need to do
|
||||
const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
|
||||
const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)]
|
||||
//TODO: Figure out how to scale this value.
|
||||
if (!!modifiers[i].LessIsGood) {
|
||||
|
||||
}
|
||||
let value = (modifiers[i].Value / modifiers[i].OriginalValue * 100 - 100) * 100;
|
||||
if (value === Infinity) {
|
||||
value = modifiers[i].Value * 100;
|
||||
}
|
||||
if (modifiers[i].Label.search('Resistance') >= 0) {
|
||||
value = (modifiers[i].Value * 100) - (modifiers[i].OriginalValue * 100)
|
||||
}
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
if (isNaN(modifierActions[action])) {
|
||||
module.setModValue(action, modifierActions[action])
|
||||
} else {
|
||||
module.setModValue(action, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the blueprint definition, grade and special
|
||||
if (blueprint) {
|
||||
module.blueprint = getBlueprint(blueprint, module)
|
||||
if (grade) {
|
||||
module.blueprint.grade = Number(grade)
|
||||
}
|
||||
if (special) {
|
||||
module.blueprint.special = special
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,10 +55,12 @@
|
||||
<!-- End Piwik Code -->
|
||||
|
||||
<!-- Bugsnag -->
|
||||
<script
|
||||
src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-3.min.js"
|
||||
data-apikey="2382691c622937f28f8fa82a1bfd797a"></script>
|
||||
|
||||
<script src="//d2wy8f7a9ursnm.cloudfront.net/v4/bugsnag.min.js"></script>
|
||||
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-plugins/v1/bugsnag-react.min.js"></script>
|
||||
<script>
|
||||
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', {appVersion: window.CORIOLIS_VERSION || undefined})
|
||||
window.Bugsnag = window.bugsnagClient
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color:#000;">
|
||||
<section id="coriolis"></section>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
@bg: rgba(30,30,30,1);
|
||||
@bgBlack: #000;
|
||||
@primary-bg: fadeout(darken(@primary, 47%), 15%);
|
||||
@alt-primary-bg: fadeout(darken(@primary, 42%), 15%); // Lighter brown background
|
||||
@secondary-bg: fadeout(darken(@secondary, @bgDarken), @bgTransparency); // Brown background
|
||||
@warning-bg: fadeout(darken(@warning, @bgDarken), @bgTransparency); // Dark Red
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ textarea {
|
||||
width:100%;
|
||||
min-height: 10em;
|
||||
resize: vertical;
|
||||
user-select: auto;
|
||||
margin:2em 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ tbody tr {
|
||||
.no-touch &.highlight:hover, .no-touch &.highlighted {
|
||||
background-color: @warning-bg;
|
||||
}
|
||||
|
||||
&.alt {
|
||||
background-color: @alt-primary-bg;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var webpack = require('webpack');
|
||||
var pkgJson = require('./package');
|
||||
var HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
var ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
const path = require('path')
|
||||
const exec = require('child_process').exec
|
||||
const webpack = require('webpack')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const WebpackNotifierPlugin = require('webpack-notifier')
|
||||
const pkgJson = require('./package')
|
||||
|
||||
function CopyDirPlugin(source, destination) {
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.source = source
|
||||
this.destination = destination
|
||||
}
|
||||
|
||||
CopyDirPlugin.prototype.apply = function (compiler) {
|
||||
compiler.plugin('done', () => {
|
||||
console.log(compiler.outputPath, this.destination)
|
||||
exec('cp -r ' + this.source + ' ' + path.join(compiler.outputPath, this.destination))
|
||||
})
|
||||
}
|
||||
CopyDirPlugin.prototype.apply = function(compiler) {
|
||||
compiler.plugin('done', function() {
|
||||
console.log(compiler.outputPath, this.destination);
|
||||
exec('cp -r ' + this.source + ' ' + path.join(compiler.outputPath, this.destination));
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
devtool: 'eval',
|
||||
devtool: 'source-map',
|
||||
devServer: {
|
||||
headers: { "Access-Control-Allow-Origin": "*" }
|
||||
headers: {'Access-Control-Allow-Origin': '*'}
|
||||
},
|
||||
entry: {
|
||||
app: [ 'webpack-dev-server/client?http://0.0.0.0:3300', 'webpack/hot/only-dev-server', path.join(__dirname, "src/app/index.js") ],
|
||||
app: ['webpack-dev-server/client?http://0.0.0.0:3300', 'webpack/hot/only-dev-server', path.join(__dirname, 'src/app/index.js')],
|
||||
lib: ['d3', 'react', 'react-dom', 'classnames', 'fbemitter', 'lz-string']
|
||||
},
|
||||
resolve: {
|
||||
@@ -37,33 +39,34 @@ module.exports = {
|
||||
plugins: [
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/.htaccess'), ''),
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'lib',
|
||||
filename: 'lib.js'
|
||||
name: 'lib',
|
||||
filename: 'lib.js'
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
inject: false,
|
||||
template: path.join(__dirname, "src/index.ejs"),
|
||||
version: pkgJson.version,
|
||||
gapiKey: process.env.CORIOLIS_GAPI_KEY || '',
|
||||
inject: false,
|
||||
template: path.join(__dirname, 'src/index.ejs'),
|
||||
version: pkgJson.version,
|
||||
gapiKey: process.env.CORIOLIS_GAPI_KEY || ''
|
||||
}),
|
||||
new ExtractTextPlugin({
|
||||
filename: 'app.css',
|
||||
disable: false,
|
||||
allChunks: true
|
||||
filename: 'app.css',
|
||||
disable: false,
|
||||
allChunks: true
|
||||
}),
|
||||
new WebpackNotifierPlugin({alwaysNotify: true}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader'}) },
|
||||
{ test: /\.less$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!less-loader'}) },
|
||||
{ test: /\.(js|jsx)$/, loaders: [ 'babel-loader' ], include: path.join(__dirname, 'src') },
|
||||
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream' },
|
||||
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
|
||||
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml' }
|
||||
{test: /\.css$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'})},
|
||||
{test: /\.less$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!less-loader'})},
|
||||
{test: /\.(js|jsx)$/, loaders: ['babel-loader'], include: path.join(__dirname, 'src')},
|
||||
{test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
|
||||
{test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
|
||||
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'},
|
||||
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'},
|
||||
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var webpack = require('webpack');
|
||||
var pkgJson = require('./package');
|
||||
var HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
var ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
var AppCachePlugin = require('appcache-webpack-plugin');
|
||||
const path = require('path')
|
||||
const exec = require('child_process').exec
|
||||
const webpack = require('webpack')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const AppCachePlugin = require('appcache-webpack-plugin')
|
||||
const {BugsnagSourceMapUploaderPlugin} = require('webpack-bugsnag-plugins')
|
||||
const pkgJson = require('./package')
|
||||
|
||||
function CopyDirPlugin(source, destination) {
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
function CopyDirPlugin (source, destination) {
|
||||
this.source = source
|
||||
this.destination = destination
|
||||
}
|
||||
|
||||
CopyDirPlugin.prototype.apply = function (compiler) {
|
||||
compiler.plugin('done', () => {
|
||||
console.log(compiler.outputPath, this.destination)
|
||||
exec('cp -r ' + this.source + ' ' + path.join(compiler.outputPath, this.destination))
|
||||
})
|
||||
}
|
||||
CopyDirPlugin.prototype.apply = function(compiler) {
|
||||
compiler.plugin('done', function() {
|
||||
console.log(compiler.outputPath, this.destination);
|
||||
exec('cp -r ' + this.source + ' ' + path.join(compiler.outputPath, this.destination));
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
cache: true,
|
||||
devtool: 'source-map',
|
||||
entry: {
|
||||
app: ['babel-polyfill', path.resolve(__dirname, 'src/app/index')],
|
||||
lib: ['d3', 'react', 'react-dom', 'classnames', 'fbemitter', 'lz-string']
|
||||
@@ -34,34 +37,39 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
'screw-ie8': true
|
||||
'screw-ie8': true,
|
||||
sourceMap: true
|
||||
}),
|
||||
//new webpack.optimize.CommonsChunkPlugin({
|
||||
// name: 'lib',
|
||||
// filename: 'lib.[chunkhash:6].js'
|
||||
//}),
|
||||
new HtmlWebpackPlugin({
|
||||
inject: false,
|
||||
appCache: 'coriolis.appcache',
|
||||
minify: {
|
||||
collapseBooleanAttributes: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true,
|
||||
removeComments: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true
|
||||
},
|
||||
template: path.join(__dirname, "src/index.ejs"),
|
||||
uaTracking: process.env.CORIOLIS_UA_TRACKING || '',
|
||||
gapiKey: process.env.CORIOLIS_GAPI_KEY || '',
|
||||
version: pkgJson.version
|
||||
inject: false,
|
||||
appCache: 'coriolis.appcache',
|
||||
minify: {
|
||||
collapseBooleanAttributes: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true,
|
||||
removeComments: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true
|
||||
},
|
||||
template: path.join(__dirname, 'src/index.ejs'),
|
||||
uaTracking: process.env.CORIOLIS_UA_TRACKING || '',
|
||||
gapiKey: process.env.CORIOLIS_GAPI_KEY || '',
|
||||
version: pkgJson.version
|
||||
}),
|
||||
new ExtractTextPlugin({
|
||||
filename: '[contenthash:6].css',
|
||||
disable: false,
|
||||
allChunks: true
|
||||
filename: '[contenthash:6].css',
|
||||
disable: false,
|
||||
allChunks: true
|
||||
}),
|
||||
new BugsnagSourceMapUploaderPlugin({
|
||||
apiKey: 'ba9fae819372850fb660755341fa6ef5',
|
||||
appVersion: pkgJson.version
|
||||
}),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/schemas'), 'schemas'),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/images/logo/*'), ''),
|
||||
@@ -75,14 +83,14 @@ module.exports = {
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader'}) },
|
||||
{ test: /\.less$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader',use: 'css-loader!less-loader'}) },
|
||||
{ test: /\.(js|jsx)$/, loader: 'babel-loader?cacheDirectory=true', include: path.join(__dirname, 'src') },
|
||||
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream' },
|
||||
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
|
||||
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml' }
|
||||
{test: /\.css$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'})},
|
||||
{test: /\.less$/, loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!less-loader'})},
|
||||
{test: /\.(js|jsx)$/, loader: 'babel-loader?cacheDirectory=true', include: path.join(__dirname, 'src')},
|
||||
{test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
|
||||
{test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
|
||||
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'},
|
||||
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'},
|
||||
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user