mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-11 08:43:02 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e060173e84 | ||
|
|
4d859da731 | ||
|
|
f2deb8675f | ||
|
|
67a4952dfd | ||
|
|
26e8cfd805 | ||
|
|
82718331ce | ||
|
|
de38f2829c | ||
|
|
b0a608b5cd | ||
|
|
307886d4ae | ||
|
|
3987c4e681 | ||
|
|
e129e1da39 | ||
|
|
8acd32b0fc | ||
|
|
f8f99a5aaa | ||
|
|
70cfa58896 | ||
|
|
56571f9c1f | ||
|
|
4ab376d9ed | ||
|
|
2858ef3e93 | ||
|
|
3215b3942d |
2
.docker/.dockerignore
Normal file
2
.docker/.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
@@ -6,28 +6,29 @@ WORKDIR /src/app
|
|||||||
RUN mkdir -p /src/app/coriolis
|
RUN mkdir -p /src/app/coriolis
|
||||||
RUN mkdir -p /src/app/coriolis-data
|
RUN mkdir -p /src/app/coriolis-data
|
||||||
|
|
||||||
RUN apk add --update git
|
COPY ./coriolis/ /src/app/coriolis
|
||||||
|
COPY ./coriolis-data/ /src/app/coriolis-data
|
||||||
|
|
||||||
COPY . /src/app/coriolis
|
RUN apk update
|
||||||
|
RUN apk add git
|
||||||
|
|
||||||
RUN npm i -g npm
|
RUN npm i -g npm
|
||||||
|
|
||||||
# Set up coriolis-data
|
# Set up coriolis-data
|
||||||
WORKDIR /src/app/coriolis-data
|
WORKDIR /src/app/coriolis-data
|
||||||
RUN git clone https://github.com/EDCD/coriolis-data.git .
|
RUN git fetch --all
|
||||||
RUN git checkout ${BRANCH}
|
|
||||||
RUN npm install --no-package-lock
|
RUN npm install --no-package-lock
|
||||||
RUN npm start
|
RUN npm start
|
||||||
|
|
||||||
# Set up coriolis
|
|
||||||
WORKDIR /src/app/coriolis
|
WORKDIR /src/app/coriolis
|
||||||
|
RUN git fetch --all
|
||||||
RUN npm install --no-package-lock
|
RUN npm install --no-package-lock
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
|
||||||
### STAGE 2: Production Environment ###
|
### STAGE 2: Production Environment ###
|
||||||
FROM fholzer/nginx-brotli as web
|
FROM nginx:1.13.12-alpine as web
|
||||||
COPY nginx.conf /etc/nginx/nginx.conf
|
COPY coriolis/.docker/nginx.conf /etc/nginx/nginx.conf
|
||||||
COPY --from=builder /src/app/coriolis/build /usr/share/nginx/html
|
COPY --from=builder /src/app/coriolis/build /usr/share/nginx/html
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
@@ -43,9 +43,6 @@ services:
|
|||||||
- "traefik.basic.port=80"
|
- "traefik.basic.port=80"
|
||||||
- "traefik.basic.protocol=http"
|
- "traefik.basic.protocol=http"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
web:
|
web:
|
||||||
external: true
|
external: true
|
||||||
45
.docker/nginx.conf
Normal file
45
.docker/nginx.conf
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
worker_processes 1;
|
||||||
|
user nobody nobody;
|
||||||
|
error_log /tmp/error.log;
|
||||||
|
pid /tmp/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
sendfile on;
|
||||||
|
client_body_temp_path /tmp/client_body;
|
||||||
|
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||||
|
proxy_temp_path /tmp/proxy_temp;
|
||||||
|
scgi_temp_path /tmp/scgi_temp;
|
||||||
|
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||||
|
access_log /tmp/access.log;
|
||||||
|
error_log /tmp/error.log;
|
||||||
|
|
||||||
|
keepalive_timeout 3000;
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
index index.html;
|
||||||
|
server_name localhost;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
autoindex on;
|
||||||
|
|
||||||
|
location ~* \.(?:manifest|appcache|html?|xml|json|css|js|map|jpg|jpeg|gif|png|ico|svg|eot|ttf|woff|woff2)$ {
|
||||||
|
expires -1;
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Credentials true;
|
||||||
|
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||||
|
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
node_modules
|
|
||||||
npm-debug.log
|
|
||||||
### Node template
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
|
||||||
typings/
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# next.js build output
|
|
||||||
.next
|
|
||||||
|
|
||||||
# nuxt.js build output
|
|
||||||
.nuxt
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless
|
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"title": "Coriolis",
|
"title": "Coriolis",
|
||||||
"description": "Coriolis Shipyard for Elite Dangerous",
|
"description": "Coriolis Shipyard for Elite Dangerous",
|
||||||
"repository": "https://github.com/EDCD/coriolis",
|
"repository": "https://github.com/EDCD/coriolis",
|
||||||
"site": "https://coriolis.io",
|
"site": "https://coriolis.edcd.io",
|
||||||
"author": "https://github.com/edcd",
|
"author": "https://github.com/edcd",
|
||||||
"image": "./src/images/logo/192x192.png"
|
"image": "./src/images/logo/192x192.png"
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
"title": "Coriolis",
|
"title": "Coriolis",
|
||||||
"description": "Coriolis Shipyard for Elite Dangerous",
|
"description": "Coriolis Shipyard for Elite Dangerous",
|
||||||
"repository": "https://github.com/EDCD/coriolis",
|
"repository": "https://github.com/EDCD/coriolis",
|
||||||
"site": "https://coriolis.io",
|
"site": "https://coriolis.edcd.io",
|
||||||
"author": "https://github.com/edcd",
|
"author": "https://github.com/edcd",
|
||||||
"image": "./src/images/logo/192x192.png"
|
"image": "./src/images/logo/192x192.png"
|
||||||
}
|
}
|
||||||
@@ -100,4 +100,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
23
Jenkinsfile
vendored
Normal file
23
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Get coriolis-data') {
|
||||||
|
steps {
|
||||||
|
sh '''YES=`echo $GIT_BRANCH | awk -F / \'{print $2}\'`
|
||||||
|
export BRANCH=`git rev-parse --abbrev-ref $YES`
|
||||||
|
rm -rf $WORKSPACE/../coriolis-data
|
||||||
|
git clone https://github.com/edcd/coriolis-data.git $WORKSPACE/../coriolis-data
|
||||||
|
cd ../coriolis-data
|
||||||
|
git fetch --all
|
||||||
|
git checkout $BRANCH'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
sshagent (credentials: ['63c9de04-3213-47c3-8345-2f3442097a5b']) {
|
||||||
|
sh 'ssh -p 56499 -o StrictHostKeyChecking=no willb@172.17.0.1 echo hi'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
nginx.conf
129
nginx.conf
@@ -1,96 +1,61 @@
|
|||||||
worker_processes 1;
|
worker_processes 2;
|
||||||
user nobody nobody;
|
error_log ./nginx.error.log;
|
||||||
error_log /tmp/error.log;
|
worker_rlimit_nofile 8192;
|
||||||
pid /tmp/nginx.pid;
|
pid nginx.pid;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
worker_connections 1024;
|
multi_accept on;
|
||||||
}
|
}
|
||||||
|
|
||||||
http {
|
http {
|
||||||
|
|
||||||
include /etc/nginx/mime.types;
|
access_log off;
|
||||||
default_type application/octet-stream;
|
charset UTF-8;
|
||||||
sendfile on;
|
|
||||||
client_body_temp_path /tmp/client_body;
|
|
||||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
|
||||||
proxy_temp_path /tmp/proxy_temp;
|
|
||||||
scgi_temp_path /tmp/scgi_temp;
|
|
||||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
|
||||||
access_log /tmp/access.log;
|
|
||||||
error_log /tmp/error.log;
|
|
||||||
|
|
||||||
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
|
types {
|
||||||
# Enable gzip compression.
|
text/html html htm shtml;
|
||||||
# Default: off
|
text/css css;
|
||||||
gzip off;
|
text/xml xml rss;
|
||||||
|
image/gif gif;
|
||||||
|
image/jpeg jpeg jpg;
|
||||||
|
application/x-javascript js;
|
||||||
|
text/plain txt;
|
||||||
|
image/png png;
|
||||||
|
image/svg+xml svg;
|
||||||
|
image/x-icon ico;
|
||||||
|
application/pdf pdf;
|
||||||
|
text/cache-manifest appcache;
|
||||||
|
}
|
||||||
|
|
||||||
# Compression level (1-9).
|
gzip on;
|
||||||
# 5 is a perfect compromise between size and CPU usage, offering about
|
gzip_vary on;
|
||||||
# 75% reduction for most ASCII files (almost identical to level 9).
|
gzip_proxied any;
|
||||||
# Default: 1
|
gzip_comp_level 6;
|
||||||
gzip_comp_level 5;
|
gzip_buffers 16 8k;
|
||||||
|
gzip_http_version 1.1;
|
||||||
|
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
|
||||||
# Don't compress anything that's already small and unlikely to shrink much
|
server {
|
||||||
# if at all (the default is 20 bytes, which is bad as that usually leads to
|
listen 3301;
|
||||||
# larger files after gzipping).
|
server_name localhost;
|
||||||
# Default: 20
|
root ./build/;
|
||||||
gzip_min_length 256;
|
index index.html;
|
||||||
|
|
||||||
# Compress data even for clients that are connecting to us via proxies,
|
location ~* \.(?:manifest|appcache|html?|xml|json|css|js|map|jpg|jpeg|gif|png|ico|svg|eot|ttf|woff|woff2)$ {
|
||||||
# identified by the "Via" header (required for CloudFront).
|
expires -1;
|
||||||
# Default: off
|
add_header Access-Control-Allow-Origin *;
|
||||||
gzip_proxied any;
|
|
||||||
|
|
||||||
# Tell proxies to cache both the gzipped and regular version of a resource
|
|
||||||
# whenever the client's Accept-Encoding capabilities header varies;
|
|
||||||
# Avoids the issue where a non-gzip capable client (which is extremely rare
|
|
||||||
# today) would display gibberish if their proxy gave them the gzipped version.
|
|
||||||
# Default: off
|
|
||||||
gzip_vary on;
|
|
||||||
|
|
||||||
# Compress all output labeled with one of the following MIME-types.
|
|
||||||
# text/html is always compressed by gzip module.
|
|
||||||
# Default: text/html
|
|
||||||
gzip_types *;
|
|
||||||
brotli on;
|
|
||||||
# brotli_static on;
|
|
||||||
brotli_types *;
|
|
||||||
# This should be turned on if you are going to have pre-compressed copies (.gz) of
|
|
||||||
# static files available. If not it should be left off as it will cause extra I/O
|
|
||||||
# for the check. It is best if you enable this in a location{} block for
|
|
||||||
# a specific directory, or on an individual server{} level.
|
|
||||||
# gzip_static on;
|
|
||||||
keepalive_timeout 3000;
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
index index.html;
|
|
||||||
server_name localhost;
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
autoindex on;
|
|
||||||
|
|
||||||
location ~* \.(?:manifest|appcache|html?|xml|json|css|js|map|jpg|jpeg|gif|png|ico|svg|eot|ttf|woff|woff2)$ {
|
|
||||||
add_header Access-Control-Allow-Origin *;
|
|
||||||
add_header Access-Control-Allow-Credentials true;
|
|
||||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
|
||||||
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
|
||||||
access_log off;
|
|
||||||
}
|
|
||||||
location /service-worker.js {
|
|
||||||
expires -1;
|
|
||||||
add_header Access-Control-Allow-Origin *;
|
|
||||||
add_header Access-Control-Allow-Credentials true;
|
add_header Access-Control-Allow-Credentials true;
|
||||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||||
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||||
access_log off;
|
access_log off;
|
||||||
}
|
}
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html =404;
|
location / {
|
||||||
}
|
try_files $uri $uri/ /index.html =404;
|
||||||
location /iframe.html {
|
}
|
||||||
try_files $uri $uri/ /iframe.html =404;
|
location /iframe.html {
|
||||||
}
|
try_files $uri $uri/ /iframe.html =404;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EDCD/coriolis"
|
"url": "https://github.com/EDCD/coriolis"
|
||||||
},
|
},
|
||||||
"homepage": "https://coriolis.io",
|
"homepage": "https://coriolis.edcd.io",
|
||||||
"bugs": "https://github.com/EDCD/coriolis/issues",
|
"bugs": "https://github.com/EDCD/coriolis/issues",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engine": "node >= 4.8.1",
|
"engine": "node >= 4.8.1",
|
||||||
@@ -120,7 +120,6 @@
|
|||||||
"webpack-notifier": "^1.6.0",
|
"webpack-notifier": "^1.6.0",
|
||||||
"workbox-webpack-plugin": "^3.6.1"
|
"workbox-webpack-plugin": "^3.6.1"
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.0.0",
|
"@babel/polyfill": "^7.0.0",
|
||||||
"browserify-zlib-next": "^1.0.1",
|
"browserify-zlib-next": "^1.0.1",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Router from './Router';
|
import Router from './Router';
|
||||||
import { register } from 'register-service-worker';
|
import { register } from 'register-service-worker'
|
||||||
import { EventEmitter } from 'fbemitter';
|
import { EventEmitter } from 'fbemitter';
|
||||||
import { getLanguage } from './i18n/Language';
|
import { getLanguage } from './i18n/Language';
|
||||||
import Persist from './stores/Persist';
|
import Persist from './stores/Persist';
|
||||||
@@ -72,7 +72,7 @@ export default class Coriolis extends React.Component {
|
|||||||
route: {},
|
route: {},
|
||||||
sizeRatio: Persist.getSizeRatio()
|
sizeRatio: Persist.getSizeRatio()
|
||||||
};
|
};
|
||||||
this._getAnnouncements();
|
this._getAnnouncements()
|
||||||
Router('', (r) => this._setPage(ShipyardPage, r));
|
Router('', (r) => this._setPage(ShipyardPage, r));
|
||||||
Router('/import?', (r) => this._importBuild(r));
|
Router('/import?', (r) => this._importBuild(r));
|
||||||
Router('/import/:data', (r) => this._importBuild(r));
|
Router('/import/:data', (r) => this._importBuild(r));
|
||||||
@@ -105,20 +105,18 @@ export default class Coriolis extends React.Component {
|
|||||||
}
|
}
|
||||||
r.params.ship = ship.id;
|
r.params.ship = ship.id;
|
||||||
r.params.code = ship.toString();
|
r.params.code = ship.toString();
|
||||||
this._setPage(OutfittingPage, r)
|
this._setPage(OutfittingPage, r);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._onError('Failed to import ship', r.path, 0, 0, err);
|
this._onError('Failed to import ship', r.path, 0, 0, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getAnnouncements() {
|
_getAnnouncements() {
|
||||||
try {
|
return request.get('https://orbis.zone/api/announcement')
|
||||||
const announces = await request.get('https://orbis.zone/api/announcement')
|
.query({showInCoriolis: true})
|
||||||
.query({ showInCoriolis: true });
|
.then(announces => {
|
||||||
this.setState({ announcements: announces.body });
|
this.setState({ announcements: announces.body })
|
||||||
} catch (err) {
|
})
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -353,27 +351,27 @@ export default class Coriolis extends React.Component {
|
|||||||
const self = this;
|
const self = this;
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
register('/service-worker.js', {
|
register('/service-worker.js', {
|
||||||
ready(registration) {
|
ready (registration) {
|
||||||
console.log('Service worker is active.');
|
console.log('Service worker is active.')
|
||||||
},
|
},
|
||||||
registered(registration) {
|
registered (registration) {
|
||||||
console.log('Service worker has been registered.');
|
console.log('Service worker has been registered.')
|
||||||
},
|
},
|
||||||
cached(registration) {
|
cached (registration) {
|
||||||
console.log('Content has been cached for offline use.');
|
console.log('Content has been cached for offline use.')
|
||||||
},
|
},
|
||||||
updatefound(registration) {
|
updatefound (registration) {
|
||||||
console.log('New content is downloading.');
|
console.log('New content is downloading.')
|
||||||
},
|
},
|
||||||
updated(registration) {
|
updated (registration) {
|
||||||
self.setState({ appCacheUpdate: true });
|
self.setState({ appCacheUpdate: true });
|
||||||
console.log('New content is available; please refresh.');
|
console.log('New content is available; please refresh.')
|
||||||
},
|
},
|
||||||
offline() {
|
offline () {
|
||||||
console.log('No internet connection found. App is running in offline mode.');
|
console.log('No internet connection found. App is running in offline mode.')
|
||||||
},
|
},
|
||||||
error(error) {
|
error (error) {
|
||||||
console.error('Error during service worker registration:', error);
|
console.error('Error during service worker registration:', error)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -396,24 +394,21 @@ export default class Coriolis extends React.Component {
|
|||||||
let currentMenu = this.state.currentMenu;
|
let currentMenu = this.state.currentMenu;
|
||||||
|
|
||||||
return <div style={{ minHeight: '100%' }} onClick={this._closeMenu}
|
return <div style={{ minHeight: '100%' }} onClick={this._closeMenu}
|
||||||
className={this.state.noTouch ? 'no-touch' : null}>
|
className={this.state.noTouch ? 'no-touch' : null}>
|
||||||
<Header announcements={this.state.announcements} appCacheUpdate={this.state.appCacheUpdate}
|
<Header announcements={this.state.announcements} appCacheUpdate={this.state.appCacheUpdate} currentMenu={currentMenu} />
|
||||||
currentMenu={currentMenu}/>
|
<div className="announcement-container">{this.state.announcements.map(a => <Announcement text={a.message}/>)}</div>
|
||||||
<div className="announcement-container">{this.state.announcements.map(a => <Announcement
|
|
||||||
text={a.message}/>)}</div>
|
|
||||||
{this.state.error ? this.state.error : this.state.page ? React.createElement(this.state.page, { currentMenu }) :
|
{this.state.error ? this.state.error : this.state.page ? React.createElement(this.state.page, { currentMenu }) :
|
||||||
<NotFoundPage/>}
|
<NotFoundPage />}
|
||||||
{this.state.modal}
|
{this.state.modal}
|
||||||
{this.state.tooltip}
|
{this.state.tooltip}
|
||||||
<footer>
|
<footer>
|
||||||
<div className="right cap">
|
<div className="right cap">
|
||||||
<a href="https://github.com/EDCD/coriolis" target="_blank" rel="noopener noreferrer"
|
<a href="https://github.com/EDCD/coriolis" target="_blank" rel="noopener noreferrer"
|
||||||
title="Coriolis Github Project">{window.CORIOLIS_VERSION} - {window.CORIOLIS_DATE}</a>
|
title="Coriolis Github Project">{window.CORIOLIS_VERSION} - {window.CORIOLIS_DATE}</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a
|
<a
|
||||||
href={'https://github.com/EDCD/coriolis/compare/edcd:develop@{' + window.CORIOLIS_DATE + '}...edcd:develop'}
|
href={'https://github.com/EDCD/coriolis/compare/edcd:develop@{' + window.CORIOLIS_DATE + '}...edcd:develop'}
|
||||||
target="_blank" rel="noopener noreferrer" title={'Coriolis Commits since' + window.CORIOLIS_DATE}>Commits
|
target="_blank" rel="noopener noreferrer" title={'Coriolis Commits since' + window.CORIOLIS_DATE}>Commits since last release
|
||||||
since last release
|
|
||||||
({window.CORIOLIS_DATE})</a>
|
({window.CORIOLIS_DATE})</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -73,12 +73,7 @@ const GRPCAT = {
|
|||||||
'gfsb': 'guardian',
|
'gfsb': 'guardian',
|
||||||
'gmrp': 'guardian',
|
'gmrp': 'guardian',
|
||||||
'gsc': 'guardian',
|
'gsc': 'guardian',
|
||||||
'ghrp': 'guardian',
|
'ghrp': 'guardian'
|
||||||
|
|
||||||
// Mining
|
|
||||||
'scl': 'mining',
|
|
||||||
'pwa': 'mining',
|
|
||||||
'sdm': 'mining'
|
|
||||||
};
|
};
|
||||||
// Order here is the order in which items will be shown in the modules menu
|
// Order here is the order in which items will be shown in the modules menu
|
||||||
const CATEGORIES = {
|
const CATEGORIES = {
|
||||||
@@ -95,7 +90,7 @@ const CATEGORIES = {
|
|||||||
'structural reinforcement': ['hr', 'mrp'],
|
'structural reinforcement': ['hr', 'mrp'],
|
||||||
'dc': ['dc'],
|
'dc': ['dc'],
|
||||||
// Hardpoints
|
// Hardpoints
|
||||||
'lasers': ['pl', 'ul', 'bl'],
|
'lasers': ['pl', 'ul', 'bl', 'ml'],
|
||||||
'projectiles': ['mc', 'c', 'fc', 'pa', 'rg'],
|
'projectiles': ['mc', 'c', 'fc', 'pa', 'rg'],
|
||||||
'ordnance': ['mr', 'tp', 'nl'],
|
'ordnance': ['mr', 'tp', 'nl'],
|
||||||
// Utilities
|
// Utilities
|
||||||
@@ -107,9 +102,7 @@ const CATEGORIES = {
|
|||||||
'experimental': ['axmc', 'axmr', 'rfl', 'tbrfl', 'tbsc', 'tbem', 'xs', 'sfn', 'rcpl', 'dtl', 'rsl', 'mahr',],
|
'experimental': ['axmc', 'axmr', 'rfl', 'tbrfl', 'tbsc', 'tbem', 'xs', 'sfn', 'rcpl', 'dtl', 'rsl', 'mahr',],
|
||||||
|
|
||||||
// Guardian
|
// Guardian
|
||||||
'guardian': ['gpp', 'gpd', 'gpc', 'ggc', 'gsrp', 'gfsb', 'ghrp', 'gmrp', 'gsc'],
|
'guardian': ['gpp', 'gpd', 'gpc', 'ggc', 'gsrp', 'gfsb', 'ghrp', 'gmrp', 'gsc']
|
||||||
|
|
||||||
'mining': ['ml', 'scl', 'pwa', 'sdm', 'abl'],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,16 +221,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
|||||||
}
|
}
|
||||||
list.push(buildGroup(grp, modules[grp]));
|
list.push(buildGroup(grp, modules[grp]));
|
||||||
for (const i of modules[grp]) {
|
for (const i of modules[grp]) {
|
||||||
let mount = '';
|
fuzzy.push({ grp, m: i, name: `${i.class}${i.rating} ${translate(grp)} ${i.mount ? i.mount : ''}` });
|
||||||
if (i.mount === 'F') {
|
|
||||||
mount = 'Fixed';
|
|
||||||
} else if (i.mount === 'G') {
|
|
||||||
mount = 'Gimballed';
|
|
||||||
} else if (i.mount === 'T') {
|
|
||||||
mount = 'Turreted';
|
|
||||||
}
|
|
||||||
const fuzz = { grp, m: i, name: `${i.class}${i.rating}${mount ? ' ' + mount : ''} ${translate(grp)}` };
|
|
||||||
fuzzy.push(fuzz);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,14 +363,10 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
|||||||
* mounted module and the hovered modules
|
* mounted module and the hovered modules
|
||||||
*/
|
*/
|
||||||
_showSearch() {
|
_showSearch() {
|
||||||
if (this.props.modules instanceof Array) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<FuzzySearch
|
<FuzzySearch
|
||||||
list={this.state.fuzzy}
|
list={this.state.fuzzy}
|
||||||
keys={['grp', 'name']}
|
keys={['grp', 'name']}
|
||||||
tokenize={true}
|
|
||||||
className={'input'}
|
className={'input'}
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
style={{ padding: 0 }}
|
style={{ padding: 0 }}
|
||||||
|
|||||||
@@ -126,9 +126,6 @@ export default class HardpointSlot extends Slot {
|
|||||||
className={'l'}>{translate('shotspeed')}: {formats.int(m.getShotSpeed())}{u.mps}</div> : null}
|
className={'l'}>{translate('shotspeed')}: {formats.int(m.getShotSpeed())}{u.mps}</div> : null}
|
||||||
{m.getPiercing() ? <div className={'l'}>{translate('piercing')}: {formats.int(m.getPiercing())}</div> : null}
|
{m.getPiercing() ? <div className={'l'}>{translate('piercing')}: {formats.int(m.getPiercing())}</div> : null}
|
||||||
{m.getJitter() ? <div className={'l'}>{translate('jitter')}: {formats.f2(m.getJitter())}°</div> : null}
|
{m.getJitter() ? <div className={'l'}>{translate('jitter')}: {formats.f2(m.getJitter())}°</div> : null}
|
||||||
{m.getScanAngle() ? <div className={'l'}>{translate('scan angle')}: {formats.f2(m.getScanAngle())}°</div> : null}
|
|
||||||
{m.getScanRange() ? <div className={'l'}>{translate('scan range')}: {formats.int(m.getScanRange())}{u.m}</div> : null}
|
|
||||||
{m.getMaxAngle() ? <div className={'l'}>{translate('max angle')}: {formats.f2(m.getMaxAngle())}°</div> : null}
|
|
||||||
{showModuleResistances && m.getExplosiveResistance() ? <div
|
{showModuleResistances && m.getExplosiveResistance() ? <div
|
||||||
className='l'>{translate('explres')}: {formats.pct(m.getExplosiveResistance())}</div> : null}
|
className='l'>{translate('explres')}: {formats.pct(m.getExplosiveResistance())}</div> : null}
|
||||||
{showModuleResistances && m.getKineticResistance() ? <div
|
{showModuleResistances && m.getKineticResistance() ? <div
|
||||||
|
|||||||
@@ -20,28 +20,16 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
super(props, context, 'standard', 'core internal');
|
super(props, context, 'standard', 'core internal');
|
||||||
this._optimizeStandard = this._optimizeStandard.bind(this);
|
this._optimizeStandard = this._optimizeStandard.bind(this);
|
||||||
this._selectBulkhead = this._selectBulkhead.bind(this);
|
this._selectBulkhead = this._selectBulkhead.bind(this);
|
||||||
this._showDW2Menu = this._showDW2Menu.bind(this);
|
|
||||||
this._dw2 = this._dw2.bind(this);
|
|
||||||
this.selectedRefId = null;
|
this.selectedRefId = null;
|
||||||
this.firstRefId = 'maxjump';
|
this.firstRefId = 'maxjump';
|
||||||
this.lastRefId = 'dw2';
|
this.lastRefId = 'racer';
|
||||||
this.state = {
|
|
||||||
showDW2: false,
|
|
||||||
DW2Tier: -1,
|
|
||||||
DW2Eng: -1,
|
|
||||||
DW2Role: '',
|
|
||||||
DW2Gfsb: false,
|
|
||||||
DW2Gpp: false,
|
|
||||||
DW2Fighter: false
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle focus if the component updates
|
* Handle focus if the component updates
|
||||||
* @param {Object} prevProps React Component properties
|
* @param {Object} prevProps React Component properties
|
||||||
*/
|
*/
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
this._handleSectionFocus(prevProps, this.firstRefId, this.lastRefId);
|
this._handleSectionFocus(prevProps,this.firstRefId, this.lastRefId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,114 +72,6 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* DW2 Build
|
|
||||||
*/
|
|
||||||
_dw2() {
|
|
||||||
this.selectedRefId = 'dw2';
|
|
||||||
this.setState({ showDW2: false });
|
|
||||||
ShipRoles.dw2Build(this.props.ship, this.state.DW2Tier, this.state.DW2Eng, this.state.DW2Role, this.state.DW2Gfsb, this.state.DW2Gpp, this.state.DW2Fighter);
|
|
||||||
this.props.ship.updateModificationsString();
|
|
||||||
this.props.onChange();
|
|
||||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
|
||||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
|
||||||
this._close();
|
|
||||||
}
|
|
||||||
|
|
||||||
_showDW2Menu(translate) {
|
|
||||||
return (
|
|
||||||
<div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
|
||||||
<div className='select-group cap'>{translate('Tier')}</div>
|
|
||||||
<ul id={'tier'}>
|
|
||||||
<li className={cn({ active: this.state.DW2Tier === 1 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Tier: 1 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('1 - Max. Jump Range, Unshielded')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Tier === 2 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Tier: 2 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('2 - Max. Jump Range, Minimal Shields')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Tier === 3 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Tier: 3 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('3 - Max. Jump Range, Optimal Shields')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Tier === 4 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Tier: 4 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('4 - Max. Jump Range, Optimal Shields & Thrusters')}</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
<div className='select-group cap'>{translate('Engineering Level')}</div>
|
|
||||||
<ul id={'engLevel'}>
|
|
||||||
<li className={cn({ active: this.state.DW2Eng === 1 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Eng: 1 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('No engineering')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Eng === 2 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Eng: 2 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('Only Felicity Farseer and Elvira Martuuk')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Eng === 3 }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Eng: 3 })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('All exploration engineers')}</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
<div className='select-group cap'>{translate('Role')}</div>
|
|
||||||
<ul id={'role'}>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'exploration' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'exploration' })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
>{translate('Space exploration')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'surface' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'surface' })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
>{translate('Surface exploration')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'materialProspector' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'materialProspector' })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
>{translate('Material prospector')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'propectorMining' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'propectorMining' })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
>{translate('Prospector/Sapper Miner')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'bigRigMining' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'bigRigMining' })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
>{translate('Big Rig, full mining')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'fuelRat' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'fuelRat' })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('Fuel Rat')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'mechanic' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'mechanic' })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('Mechanic')}</li>
|
|
||||||
<li className={cn({ active: this.state.DW2Role === 'trucker' }, 'lc')} tabIndex="0"
|
|
||||||
onClick={() => this.setState({ DW2Role: 'trucker' })} onKeyDown={this._keyDown}
|
|
||||||
>{translate('Trucker')}</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
<ul>
|
|
||||||
<li className={cn({ active: this.state.DW2Gfsb === true }, 'lc')}
|
|
||||||
onClick={() => this.setState({ DW2Gfsb: this.state.DW2Gfsb !== true })}>
|
|
||||||
Add Guardian FSD Booster
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li className={cn({ active: this.state.DW2Gpp === true }, 'lc')}
|
|
||||||
onClick={() => this.setState({ DW2Gpp: this.state.DW2Gpp !== true })}>
|
|
||||||
Add Guardian Power Plant
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li className={cn({ active: this.state.DW2Fighter === true }, 'lc')}
|
|
||||||
onClick={() => this.setState({ DW2Fighter: this.state.DW2Fighter !== true })}>
|
|
||||||
Add Fighter
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
<ul>
|
|
||||||
<li onClick={this._dw2} className={cn('lc')} tabIndex="0"
|
|
||||||
onKeyDown={this._keyDown}>
|
|
||||||
<button className="button">Apply</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Miner Build
|
* Miner Build
|
||||||
* @param {Boolean} shielded True if shield generator should be included
|
* @param {Boolean} shielded True if shield generator should be included
|
||||||
@@ -297,6 +177,7 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
warning={m => m instanceof Module ? m.getMaxMass() < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass) : m.maxmass < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass)}
|
warning={m => m instanceof Module ? m.getMaxMass() < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass) : m.maxmass < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass)}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
|
|
||||||
slots[3] = <StandardSlot
|
slots[3] = <StandardSlot
|
||||||
key='fsd'
|
key='fsd'
|
||||||
slot={st[2]}
|
slot={st[2]}
|
||||||
@@ -351,7 +232,7 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
selected={currentMenu == st[6]}
|
selected={currentMenu == st[6]}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
warning={m => m.fuel < st[2].m.maxfuel} // Show warning when fuel tank is smaller than FSD Max Fuel
|
warning= {m => m.fuel < st[2].m.maxfuel} // Show warning when fuel tank is smaller than FSD Max Fuel
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
return slots;
|
return slots;
|
||||||
@@ -364,34 +245,19 @@ export default class StandardSlotSection extends SlotSection {
|
|||||||
*/
|
*/
|
||||||
_getSectionMenu(translate) {
|
_getSectionMenu(translate) {
|
||||||
let planetaryDisabled = this.props.ship.internal.length < 4;
|
let planetaryDisabled = this.props.ship.internal.length < 4;
|
||||||
if (this.state.showDW2 === true) {
|
|
||||||
return this._showDW2Menu(translate);
|
|
||||||
}
|
|
||||||
return <div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
return <div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||||
<ul>
|
<ul>
|
||||||
<li className='lc' tabIndex="0" onClick={this._optimizeStandard} onKeyDown={this._keyDown}
|
<li className='lc' tabIndex="0" onClick={this._optimizeStandard} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['maxjump'] = smRef}>{translate('Maximize Jump Range')}</li>
|
||||||
ref={smRef => this.sectionRefArr['maxjump'] = smRef}>{translate('Maximize Jump Range')}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div className='select-group cap'>{translate('roles')}</div>
|
<div className='select-group cap'>{translate('roles')}</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, false, 0)} onKeyDown={this._keyDown}
|
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, false, 0)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['multipurpose'] = smRef}>{translate('Multi-purpose')}</li>
|
||||||
ref={smRef => this.sectionRefArr['multipurpose'] = smRef}>{translate('Multi-purpose')}</li>
|
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, true, 2)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['combat'] = smRef}>{translate('Combat')}</li>
|
||||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, true, 2)} onKeyDown={this._keyDown}
|
<li className='lc' tabIndex="0" onClick={this._optimizeCargo.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['trader'] = smRef}>{translate('Trader')}</li>
|
||||||
ref={smRef => this.sectionRefArr['combat'] = smRef}>{translate('Combat')}</li>
|
<li className='lc' tabIndex="0" onClick={this._optimizeExplorer.bind(this, false)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['explorer'] = smRef}>{translate('Explorer')}</li>
|
||||||
<li className='lc' tabIndex="0" onClick={this._optimizeCargo.bind(this, true)} onKeyDown={this._keyDown}
|
<li className={cn('lc', { disabled: planetaryDisabled })} tabIndex={planetaryDisabled ? '' : '0'} onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['planetary'] = smRef}>{translate('Planetary Explorer')}</li>
|
||||||
ref={smRef => this.sectionRefArr['trader'] = smRef}>{translate('Trader')}</li>
|
<li className='lc' tabIndex="0" onClick={this._optimizeMiner.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['miner'] = smRef}>{translate('Miner')}</li>
|
||||||
<li className='lc' tabIndex="0" onClick={this._optimizeExplorer.bind(this, false)} onKeyDown={this._keyDown}
|
<li className='lc' tabIndex="0" onClick={this._optimizeRacer.bind(this)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['racer'] = smRef}>{translate('Racer')}</li>
|
||||||
ref={smRef => this.sectionRefArr['explorer'] = smRef}>{translate('Explorer')}</li>
|
|
||||||
<li className={cn('lc', { disabled: planetaryDisabled })} tabIndex={planetaryDisabled ? '' : '0'}
|
|
||||||
onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)} onKeyDown={this._keyDown}
|
|
||||||
ref={smRef => this.sectionRefArr['planetary'] = smRef}>{translate('Planetary Explorer')}</li>
|
|
||||||
<li className='lc' tabIndex="0" onClick={this._optimizeMiner.bind(this, true)} onKeyDown={this._keyDown}
|
|
||||||
ref={smRef => this.sectionRefArr['miner'] = smRef}>{translate('Miner')}</li>
|
|
||||||
<li className='lc' tabIndex="0" onClick={this._optimizeRacer.bind(this)} onKeyDown={this._keyDown}
|
|
||||||
ref={smRef => this.sectionRefArr['racer'] = smRef}>{translate('Racer')}</li>
|
|
||||||
<li className='lc' tabIndex="0" onClick={() => this.setState({ showDW2: !this.state.showDW2 })}
|
|
||||||
onKeyDown={this._keyDown}
|
|
||||||
ref={smRef => this.sectionRefArr['dw2'] = smRef}>{translate('DW2')}</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,10 +132,6 @@
|
|||||||
"gfsb": "Guardian Frame Shift Drive Booster",
|
"gfsb": "Guardian Frame Shift Drive Booster",
|
||||||
"ghrp": "Guardian Hull Reinforcement Package",
|
"ghrp": "Guardian Hull Reinforcement Package",
|
||||||
"gmrp": "Guardian Module Reinforcement Package",
|
"gmrp": "Guardian Module Reinforcement Package",
|
||||||
"pwa": "Pulse Wave Analyser",
|
|
||||||
"abl": "Abrasion Blaster",
|
|
||||||
"scl": "Seismic Charge Launcher",
|
|
||||||
"sdm": "Sub-Surface Displacement Missile",
|
|
||||||
"tbsc": "Shock Cannon",
|
"tbsc": "Shock Cannon",
|
||||||
"gsc": "Guardian Shard Cannon",
|
"gsc": "Guardian Shard Cannon",
|
||||||
"psg": "Prismatic Shield Generator",
|
"psg": "Prismatic Shield Generator",
|
||||||
@@ -238,7 +234,6 @@
|
|||||||
"rof": "Rate of fire",
|
"rof": "Rate of fire",
|
||||||
"angle": "Scan angle",
|
"angle": "Scan angle",
|
||||||
"scanrate": "Scan rate",
|
"scanrate": "Scan rate",
|
||||||
"proberadius": "Probe Radius",
|
|
||||||
"scantime": "Scan time",
|
"scantime": "Scan time",
|
||||||
"shield": "Shield",
|
"shield": "Shield",
|
||||||
"armour": "Armour",
|
"armour": "Armour",
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default class AboutPage extends Page {
|
|||||||
patreon.com/coriolis_elite
|
patreon.com/coriolis_elite
|
||||||
</a>
|
</a>
|
||||||
, which will be used to keep Coriolis up to date and the servers
|
, which will be used to keep Coriolis up to date and the servers
|
||||||
running.
|
running. I also run ads, which are also used for development and hosting.
|
||||||
</p>
|
</p>
|
||||||
<form
|
<form
|
||||||
action="https://www.paypal.com/cgi-bin/webscr"
|
action="https://www.paypal.com/cgi-bin/webscr"
|
||||||
|
|||||||
@@ -224,12 +224,9 @@ export default class OutfittingPage extends Page {
|
|||||||
const control = LZString.decompressFromBase64(
|
const control = LZString.decompressFromBase64(
|
||||||
Utils.fromUrlSafe(parts[4])
|
Utils.fromUrlSafe(parts[4])
|
||||||
).split('/');
|
).split('/');
|
||||||
sys = parseFloat(control[0]);
|
sys = parseFloat(control[0]) || sys;
|
||||||
eng = parseFloat(control[1]);
|
eng = parseFloat(control[1]) || eng;
|
||||||
wep = parseFloat(control[2]);
|
wep = parseFloat(control[2]) || wep;
|
||||||
if (sys + eng + wep > 6) {
|
|
||||||
sys = eng = wep = 2;
|
|
||||||
}
|
|
||||||
boost = control[3] == 1 ? true : false;
|
boost = control[3] == 1 ? true : false;
|
||||||
fuel = parseFloat(control[4]) || fuel;
|
fuel = parseFloat(control[4]) || fuel;
|
||||||
cargo = parseInt(control[5]) || cargo;
|
cargo = parseInt(control[5]) || cargo;
|
||||||
|
|||||||
@@ -70,13 +70,6 @@ export default class Page extends React.Component {
|
|||||||
document.title = this.state.title || 'Coriolis';
|
document.title = this.state.title || 'Coriolis';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the window title upon mount
|
|
||||||
*/
|
|
||||||
componentDidMount() {
|
|
||||||
document.title = this.state.title || 'Coriolis';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the title upon change
|
* Updates the title upon change
|
||||||
* @param {Object} newProps Incoming properties
|
* @param {Object} newProps Incoming properties
|
||||||
|
|||||||
@@ -169,9 +169,10 @@ export default class ShipyardPage extends Page {
|
|||||||
* @param {Object} u Localized unit map
|
* @param {Object} u Localized unit map
|
||||||
* @param {Function} fInt Localized integer formatter
|
* @param {Function} fInt Localized integer formatter
|
||||||
* @param {Function} fRound Localized round formatter
|
* @param {Function} fRound Localized round formatter
|
||||||
|
* @param {Boolean} highlight Should this row be highlighted
|
||||||
* @return {React.Component} Table Row
|
* @return {React.Component} Table Row
|
||||||
*/
|
*/
|
||||||
_shipRowElement(s, translate, u, fInt, fRound) {
|
_shipRowElement(s, translate, u, fInt, fRound, highlight) {
|
||||||
let noTouch = this.context.noTouch;
|
let noTouch = this.context.noTouch;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -180,6 +181,7 @@ export default class ShipyardPage extends Page {
|
|||||||
style={{ height: '1.5em' }}
|
style={{ height: '1.5em' }}
|
||||||
className={cn({
|
className={cn({
|
||||||
highlighted: noTouch && this.state.shipId === s.id,
|
highlighted: noTouch && this.state.shipId === s.id,
|
||||||
|
alt: highlight
|
||||||
})}
|
})}
|
||||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||||
>
|
>
|
||||||
@@ -284,13 +286,27 @@ export default class ShipyardPage extends Page {
|
|||||||
let shipRows = new Array(shipSummaries.length);
|
let shipRows = new Array(shipSummaries.length);
|
||||||
let detailRows = new Array(shipSummaries.length);
|
let detailRows = new Array(shipSummaries.length);
|
||||||
|
|
||||||
|
let lastShipSortValue = null;
|
||||||
|
let backgroundHighlight = false;
|
||||||
|
|
||||||
for (let s of shipSummaries) {
|
for (let s of shipSummaries) {
|
||||||
|
let shipSortValue = s[shipPredicate];
|
||||||
|
if (shipPredicateIndex != undefined) {
|
||||||
|
shipSortValue = shipSortValue[shipPredicateIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shipSortValue != lastShipSortValue) {
|
||||||
|
backgroundHighlight = !backgroundHighlight;
|
||||||
|
lastShipSortValue = shipSortValue;
|
||||||
|
}
|
||||||
|
|
||||||
detailRows[i] = this._shipRowElement(
|
detailRows[i] = this._shipRowElement(
|
||||||
s,
|
s,
|
||||||
translate,
|
translate,
|
||||||
units,
|
units,
|
||||||
fInt,
|
fInt,
|
||||||
formats.f1,
|
formats.f1,
|
||||||
|
backgroundHighlight
|
||||||
);
|
);
|
||||||
shipRows[i] = (
|
shipRows[i] = (
|
||||||
<tr
|
<tr
|
||||||
@@ -298,6 +314,7 @@ export default class ShipyardPage extends Page {
|
|||||||
style={{ height: '1.5em' }}
|
style={{ height: '1.5em' }}
|
||||||
className={cn({
|
className={cn({
|
||||||
highlighted: noTouch && this.state.shipId === s.id,
|
highlighted: noTouch && this.state.shipId === s.id,
|
||||||
|
alt: backgroundHighlight
|
||||||
})}
|
})}
|
||||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -94,10 +94,6 @@ export const ModuleGroupToName = {
|
|||||||
gsc: 'Guardian Shard Cannon',
|
gsc: 'Guardian Shard Cannon',
|
||||||
tbem: 'Enzyme Missile Rack',
|
tbem: 'Enzyme Missile Rack',
|
||||||
tbrfl: 'Remote Release Flechette Launcher',
|
tbrfl: 'Remote Release Flechette Launcher',
|
||||||
pwa: 'Pulse Wave Analyser',
|
|
||||||
abl: 'Abrasion Blaster',
|
|
||||||
scl: 'Seismic Charge Launcher',
|
|
||||||
sdm: 'Sub-Surface Displacement Missile',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let GrpNameToCodeMap = {};
|
let GrpNameToCodeMap = {};
|
||||||
|
|||||||
@@ -1073,31 +1073,4 @@ export default class Module {
|
|||||||
getHackTime(modified = true) {
|
getHackTime(modified = true) {
|
||||||
return this.get('hacktime', modified);
|
return this.get('hacktime', modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scan range for this module
|
|
||||||
* @param {Boolean} [modified=true] Whether to take modifications into account
|
|
||||||
* @return {string} the time for this module
|
|
||||||
*/
|
|
||||||
getScanRange(modified = true) {
|
|
||||||
return this.get('scanrange', modified);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scan angle for this module
|
|
||||||
* @param {Boolean} [modified=true] Whether to take modifications into account
|
|
||||||
* @return {string} the time for this module
|
|
||||||
*/
|
|
||||||
getScanAngle(modified = true) {
|
|
||||||
return this.get('scanangle', modified);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the max angle for this module
|
|
||||||
* @param {Boolean} [modified=true] Whether to take modifications into account
|
|
||||||
* @return {string} the time for this module
|
|
||||||
*/
|
|
||||||
getMaxAngle(modified = true) {
|
|
||||||
return this.get('maxangle', modified);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,13 +164,13 @@ export default class ModuleSet {
|
|||||||
/**
|
/**
|
||||||
* Finds the lightest usable Shield Generator
|
* Finds the lightest usable Shield Generator
|
||||||
* @param {number} hullMass Ship hull mass
|
* @param {number} hullMass Ship hull mass
|
||||||
* @param {string} rating The optional rating of the shield
|
* @return {Object} Thruster
|
||||||
* @return {Object} Shield Generator
|
|
||||||
*/
|
*/
|
||||||
lightestShieldGenerator(hullMass, rating) {
|
lightestShieldGenerator(hullMass) {
|
||||||
let sg = this.internal.sg[0];
|
let sg = this.internal.sg[0];
|
||||||
|
|
||||||
for (let s of this.internal.sg) {
|
for (let s of this.internal.sg) {
|
||||||
if ((!rating || rating === s.rating) && s.mass <= sg.mass && s.maxmass > hullMass) {
|
if (s.mass < sg.mass && s.maxmass > hullMass) {
|
||||||
sg = s;
|
sg = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ export function toDetailedBuild(buildName, ship) {
|
|||||||
code = ship.toString();
|
code = ship.toString();
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
$schema: 'https://coriolis.io/schemas/ship-loadout/4.json#',
|
$schema: 'https://coriolis.edcd.io/schemas/ship-loadout/4.json#',
|
||||||
name: buildName,
|
name: buildName,
|
||||||
ship: ship.name,
|
ship: ship.name,
|
||||||
references: [{
|
references: [{
|
||||||
name: 'Coriolis.io',
|
name: 'Coriolis.io',
|
||||||
url: 'https://coriolis.io' + outfitURL(ship.id, code, buildName),
|
url: 'https://coriolis.edcd.io' + outfitURL(ship.id, code, buildName),
|
||||||
code,
|
code,
|
||||||
shipId: ship.id
|
shipId: ship.id
|
||||||
}],
|
}],
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import * as ModuleUtils from './ModuleUtils';
|
import * as ModuleUtils from './ModuleUtils';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
|
||||||
import { canMount } from '../utils/SlotFunctions';
|
import { canMount } from '../utils/SlotFunctions';
|
||||||
import { getBlueprint, setPercent } from '../utils/BlueprintFunctions';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
||||||
@@ -16,7 +14,7 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
|||||||
.useBulkhead(bulkheadIndex);
|
.useBulkhead(bulkheadIndex);
|
||||||
|
|
||||||
if (shielded) {
|
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
|
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||||
ship.setSlotEnabled(slot, true);
|
ship.setSlotEnabled(slot, true);
|
||||||
@@ -26,577 +24,6 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Distant Worlds 2 role
|
|
||||||
* Tiers:
|
|
||||||
* 1- Max. Jump Range, Unshielded
|
|
||||||
* 2- Max. Jump Range, Minimal Shields
|
|
||||||
* 3- Max. Jump Range, Optimal Shields
|
|
||||||
* 4- Max. Jump Range, Optimal Shields & Thrusters
|
|
||||||
*
|
|
||||||
* Engineering level:
|
|
||||||
* No engineering
|
|
||||||
* Only Felicity Farseer and Elvira Martuuk
|
|
||||||
* All exploration related engineers
|
|
||||||
*
|
|
||||||
* Role
|
|
||||||
* Exploration
|
|
||||||
* Surface exploration
|
|
||||||
* Big Rig, full mining
|
|
||||||
* Saper / Prospector mining
|
|
||||||
* Fuel rat
|
|
||||||
* Repair rat
|
|
||||||
* Mechanic
|
|
||||||
* Trucker
|
|
||||||
*
|
|
||||||
* @param ship {Ship} Ship instance
|
|
||||||
* @param tier {Number}
|
|
||||||
* @param engineeringLevel {Number}
|
|
||||||
* @param role {String}
|
|
||||||
* @param gfsb {Boolean} add Guardian FSD Booster
|
|
||||||
* @param gpp {Boolean} add Guardian Power Plant
|
|
||||||
* @param fighter {Boolean} add fighter if supported
|
|
||||||
*/
|
|
||||||
export function dw2Build(ship, tier, engineeringLevel, role, gfsb, gpp, fighter) {
|
|
||||||
ship
|
|
||||||
.emptyInternal()
|
|
||||||
.emptyHardpoints()
|
|
||||||
.emptyUtility();
|
|
||||||
const fsd = ModuleUtils.findStandard('fsd', ship.standard[2].maxClass, 'A');
|
|
||||||
ship.use(ship.standard[2], fsd);
|
|
||||||
ship.use(ship.standard[3], ModuleUtils.findStandard('ls', ship.standard[3].maxClass, 'D'));
|
|
||||||
ship.use(ship.standard[4], ModuleUtils.findStandard('pd', 1, 'D'));
|
|
||||||
ship.use(ship.standard[5], ModuleUtils.findStandard('s', ship.standard[5].maxClass, 'D'));
|
|
||||||
const fuelNeeded = ship.standard[2].m.maxfuel * 2;
|
|
||||||
const fuelTank = ship.availCS.standard[6]
|
|
||||||
.filter(e => e.fuel)
|
|
||||||
.filter(e => e.fuel >= fuelNeeded);
|
|
||||||
ship.use(ship.standard[6], fuelTank[0]);
|
|
||||||
ship.useBulkhead(0, false);
|
|
||||||
if (engineeringLevel === 2) {
|
|
||||||
const bp = getBlueprint('FSD_LongRange', ship.standard[2]);
|
|
||||||
bp.grade = 5;
|
|
||||||
bp.special = Modifications.specials['special_fsd_heavy'];
|
|
||||||
ship.standard[2].m.blueprint = bp;
|
|
||||||
setPercent(ship, ship.standard[2].m, 100);
|
|
||||||
// Sensors G3 LW
|
|
||||||
const sBP = getBlueprint('Sensor_Sensor_LightWeight', ship.standard[5]);
|
|
||||||
sBP.grade = 3;
|
|
||||||
ship.standard[5].m.blueprint = sBP;
|
|
||||||
setPercent(ship, ship.standard[5].m, 100);
|
|
||||||
} else if (engineeringLevel === 3) {
|
|
||||||
// Armour G5 HD + Deep Plating
|
|
||||||
const armourBP = getBlueprint('Armour_HeavyDuty', ship.bulkheads);
|
|
||||||
armourBP.grade = 5;
|
|
||||||
armourBP.special = Modifications.specials['special_armour_chunky'];
|
|
||||||
ship.bulkheads.m.blueprint = armourBP;
|
|
||||||
setPercent(ship, ship.bulkheads.m, 100);
|
|
||||||
// FSD G5 IR + Mass Manager
|
|
||||||
const fsdBP = getBlueprint('FSD_LongRange', ship.standard[2]);
|
|
||||||
fsdBP.grade = 5;
|
|
||||||
fsdBP.special = Modifications.specials['special_fsd_heavy'];
|
|
||||||
ship.standard[2].m.blueprint = fsdBP;
|
|
||||||
setPercent(ship, ship.standard[2].m, 100);
|
|
||||||
// LS G4 LW
|
|
||||||
const lsBP = getBlueprint('LifeSupport_LightWeight', ship.standard[3]);
|
|
||||||
lsBP.grade = 4;
|
|
||||||
ship.standard[3].m.blueprint = lsBP;
|
|
||||||
setPercent(ship, ship.standard[3].m, 100);
|
|
||||||
// Sensors G5 LW
|
|
||||||
const sBP = getBlueprint('Sensor_Sensor_LightWeight', ship.standard[5]);
|
|
||||||
sBP.grade = 5;
|
|
||||||
ship.standard[5].m.blueprint = sBP;
|
|
||||||
setPercent(ship, ship.standard[5].m, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ship.id === 'imperial_clipper') {
|
|
||||||
const fs = ModuleUtils.findInternal('fs', 4, 'A');
|
|
||||||
const slot = ship.internal.filter(a => a.maxClass === 4)[0];
|
|
||||||
ship.use(slot, fs);
|
|
||||||
} else if (ship.id === 'imperial_cutter') {
|
|
||||||
const fs = ModuleUtils.findInternal('fs', 6, 'A');
|
|
||||||
const slot = ship.internal.filter(a => a.maxClass === 6)[0];
|
|
||||||
ship.use(slot, fs);
|
|
||||||
} else if (fsd.class === 2 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 2, 'A');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 2).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 1, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 1)[0];
|
|
||||||
ship.use(slot, fs);
|
|
||||||
} else {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else if (fsd.class === 3 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 3, 'B');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 3).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 2, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 2)[0];
|
|
||||||
ship.use(slot, fs);
|
|
||||||
} else {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else if (fsd.class === 4 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 4, 'b');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 4).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 3, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 3)[0];
|
|
||||||
ship.use(slot, fs);
|
|
||||||
} else {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else if (fsd.class === 5 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 5, 'B');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 5).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 4, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 4).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (fsd.class === 6 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 6, 'B');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 6)
|
|
||||||
.filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 5, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 5)[0];
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (fsd.class === 7 && fsd.rating === 'A') {
|
|
||||||
let fs = ModuleUtils.findInternal('fs', 7, 'B');
|
|
||||||
let slot = ship.internal.filter(a => a.maxClass >= 7).filter(a => a.maxClass >= fs.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (slot && slot.m) {
|
|
||||||
fs = ModuleUtils.findInternal('fs', 6, 'A');
|
|
||||||
slot = ship.internal.filter(a => a.maxClass === 6)[0];
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fs) {
|
|
||||||
ship.use(slot, fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tier !== 1) {
|
|
||||||
const fuelNeeded = ship.standard[2].m.maxfuel * 3;
|
|
||||||
const fuelTank = ship.availCS.standard[6]
|
|
||||||
.filter(e => e.fuel)
|
|
||||||
.filter(e => e.fuel >= fuelNeeded);
|
|
||||||
if (fuelTank[0]) {
|
|
||||||
ship.use(ship.standard[6], fuelTank[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tier === 2) {
|
|
||||||
if (ship.id === 'alliance_chieftain' || ship.id === 'alliance_crusader' || ship.id === 'federal_gunship' || ship.id === 'vulture') {
|
|
||||||
const hrp = ModuleUtils.findInternal('hrp', 3, 'D');
|
|
||||||
const slot = ship.internal.filter(e => e.eligible && e.maxClass === 3);
|
|
||||||
if (hrp) {
|
|
||||||
ship.use(slot, hrp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const sg = ship.getAvailableModules().lightestShieldGenerator(ship.ladenMass);
|
|
||||||
const slot = ship.internal.filter(a => !a.m)
|
|
||||||
.filter(a => a.maxClass >= sg.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (sg) {
|
|
||||||
ship.use(slot, sg);
|
|
||||||
}
|
|
||||||
if (engineeringLevel === 2) {
|
|
||||||
// ELP G3
|
|
||||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
|
||||||
shieldBP.grade = 3;
|
|
||||||
ship.findShieldGenerator().blueprint = shieldBP;
|
|
||||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
|
||||||
} else if (engineeringLevel === 3) {
|
|
||||||
// ELP G5
|
|
||||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
|
||||||
shieldBP.grade = 5;
|
|
||||||
ship.findShieldGenerator().blueprint = shieldBP;
|
|
||||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
|
||||||
}
|
|
||||||
// const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8].reverse();
|
|
||||||
// const shieldInternals = ship.internal.filter(a => !a.m)
|
|
||||||
// .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);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
} else if (tier === 3 || tier === 4) {
|
|
||||||
const sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass, 'A');
|
|
||||||
const slot = ship.internal.filter(a => !a.m)
|
|
||||||
.filter(a => a.maxClass >= sg.class)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
if (sg) {
|
|
||||||
ship.use(slot, sg);
|
|
||||||
}
|
|
||||||
if (engineeringLevel === 1) {
|
|
||||||
// ELP G3
|
|
||||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
|
||||||
shieldBP.grade = 3;
|
|
||||||
shieldBP.special = Modifications.specials['special_shield_lightweight'];
|
|
||||||
ship.findShieldGenerator().blueprint = shieldBP;
|
|
||||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
|
||||||
} else if (engineeringLevel === 2) {
|
|
||||||
// ELP G5
|
|
||||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
|
||||||
shieldBP.grade = 5;
|
|
||||||
shieldBP.special = Modifications.specials['special_shield_lightweight'];
|
|
||||||
ship.findShieldGenerator().blueprint = shieldBP;
|
|
||||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tier === 4) {
|
|
||||||
let t;
|
|
||||||
if (canMount(ship, ship.standard[1], 't', ship.standard[1].maxClass - 1)) {
|
|
||||||
t = ModuleUtils.findStandard('t', ship.standard[1].maxClass - 1, 'A');
|
|
||||||
} else {
|
|
||||||
t = ModuleUtils.findStandard('t', ship.standard[1].maxClass, 'A');
|
|
||||||
}
|
|
||||||
if (t) {
|
|
||||||
ship.use(ship.standard[1], t);
|
|
||||||
}
|
|
||||||
if (engineeringLevel === 1) {
|
|
||||||
// DD G3
|
|
||||||
const tBP = getBlueprint('Engine_Dirty', ship.standard[1]);
|
|
||||||
tBP.grade = 3;
|
|
||||||
tBP.special = Modifications.specials['special_engine_lightweight'];
|
|
||||||
ship.standard[1].m.blueprint = tBP;
|
|
||||||
setPercent(ship, ship.standard[1].m, 100);
|
|
||||||
} else if (engineeringLevel === 2) {
|
|
||||||
// DD G5
|
|
||||||
const tBP = getBlueprint('Engine_Dirty', ship.standard[1]);
|
|
||||||
tBP.grade = 5;
|
|
||||||
tBP.special = Modifications.specials['special_engine_lightweight'];
|
|
||||||
ship.standard[1].m.blueprint = tBP;
|
|
||||||
setPercent(ship, ship.standard[1].m, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tier === 4 || tier === 3) {
|
|
||||||
if (engineeringLevel === 3) {
|
|
||||||
const pd = ship.availCS.standard[4]
|
|
||||||
.filter(d => d.rating === 'D')
|
|
||||||
.filter(d => (d.engcap * 1.728) >= ship.boostEnergy)
|
|
||||||
.sort((a, b) => a.class.toString().localeCompare(b.class.toString()))[0];
|
|
||||||
if (pd) {
|
|
||||||
ship.use(ship.standard[4], pd);
|
|
||||||
}
|
|
||||||
// CE G5
|
|
||||||
const pdBP = getBlueprint('PowerDistributor_HighFrequency', ship.standard[4]);
|
|
||||||
pdBP.grade = 5;
|
|
||||||
pdBP.special = Modifications.specials['special_powerdistributor_capacity'];
|
|
||||||
ship.standard[4].m.blueprint = pdBP;
|
|
||||||
setPercent(ship, ship.standard[4].m, 100);
|
|
||||||
} else {
|
|
||||||
const pd = ship.availCS.standard[4]
|
|
||||||
.filter(d => d.rating === 'D')
|
|
||||||
.sort((a, b) => a.engcap > b.engcap)
|
|
||||||
[0];
|
|
||||||
if (pd) {
|
|
||||||
ship.use(ship.standard[4], pd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (tier === 4) {
|
|
||||||
if (engineeringLevel === 3) {
|
|
||||||
const pd = ship.availCS.standard[4]
|
|
||||||
.filter(d => d.rating === 'D')
|
|
||||||
.sort((a, b) => b.class.toString().localeCompare(a.class.toString()))[0];
|
|
||||||
if (pd) {
|
|
||||||
ship.use(ship.standard[4], pd);
|
|
||||||
}
|
|
||||||
// CE G5
|
|
||||||
const pdBP = getBlueprint('PowerDistributor_HighFrequency', ship.standard[4]);
|
|
||||||
pdBP.grade = 5;
|
|
||||||
pdBP.special = Modifications.specials['special_powerdistributor_capacity'];
|
|
||||||
ship.standard[4].m.blueprint = pdBP;
|
|
||||||
setPercent(ship, ship.standard[4].m, 100);
|
|
||||||
} else {
|
|
||||||
const pd = ship.availCS.standard[4]
|
|
||||||
.filter(d => d.rating === 'D')
|
|
||||||
.sort((a, b) => b.class.toString().localeCompare(a.class.toString()))[0];
|
|
||||||
if (pd) {
|
|
||||||
ship.use(ship.standard[4], pd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ship.fighterHangars && fighter) {
|
|
||||||
const slot = ship.internal.filter(s => s.maxClass >= 5 && !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
|
||||||
[0];
|
|
||||||
const mod = ModuleUtils.findInternal('fh', 5, 'D');
|
|
||||||
if (slot && mod) {
|
|
||||||
ship.use(slot, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tier === 1) {
|
|
||||||
const pd = ModuleUtils.findStandard('pd', 1, 'D');
|
|
||||||
if (pd) {
|
|
||||||
ship.use(ship.standard[4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dssPriority = 0;
|
|
||||||
let srvPriority = 0;
|
|
||||||
let afmu = true;
|
|
||||||
let cargo = false;
|
|
||||||
let miningLaserPriority = 0;
|
|
||||||
let refinery = false;
|
|
||||||
let collector = false;
|
|
||||||
let prospector = false;
|
|
||||||
let miningTools = false;
|
|
||||||
let refuelLimpets = false;
|
|
||||||
let repairLimpets = false;
|
|
||||||
console.log(role);
|
|
||||||
if (role === 'exploration') {
|
|
||||||
dssPriority = 2;
|
|
||||||
afmu = true;
|
|
||||||
} else if (role === 'surface') {
|
|
||||||
dssPriority = 2;
|
|
||||||
srvPriority = 2;
|
|
||||||
} else if (role === 'materialProspector') {
|
|
||||||
miningLaserPriority = 2;
|
|
||||||
srvPriority = 1;
|
|
||||||
} else if (role === 'propectorMining') {
|
|
||||||
dssPriority = 1;
|
|
||||||
prospector = true;
|
|
||||||
miningLaserPriority = 1;
|
|
||||||
cargo = true;
|
|
||||||
miningTools = true;
|
|
||||||
|
|
||||||
} else if (role === 'bigRigMining') {
|
|
||||||
dssPriority = 1;
|
|
||||||
miningLaserPriority = 2;
|
|
||||||
cargo = true;
|
|
||||||
collector = true;
|
|
||||||
refinery = true;
|
|
||||||
miningTools = true;
|
|
||||||
|
|
||||||
} else if (role === 'fuelRat') {
|
|
||||||
refuelLimpets = true;
|
|
||||||
cargo = true;
|
|
||||||
srvPriority = 1;
|
|
||||||
|
|
||||||
} else if (role === 'mechanic') {
|
|
||||||
repairLimpets = true;
|
|
||||||
cargo = true;
|
|
||||||
srvPriority = 1;
|
|
||||||
} else if (role === 'trucker') {
|
|
||||||
cargo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dssPriority === 2) {
|
|
||||||
const mod = ModuleUtils.findModule('ss', '2i');
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
console.log(slot);
|
|
||||||
console.log(mod);
|
|
||||||
ship.use(slot, mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srvPriority === 2) {
|
|
||||||
let mod;
|
|
||||||
let slot = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 6)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
if (slot) {
|
|
||||||
mod = ModuleUtils.findModule('pv', 'v2');
|
|
||||||
ship.use(slot, mod);
|
|
||||||
} else if (!slot) {
|
|
||||||
slot = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 4)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
if (slot) {
|
|
||||||
mod = ModuleUtils.findModule('pv', 'v4');
|
|
||||||
ship.use(slot, mod);
|
|
||||||
} else {
|
|
||||||
slot = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 2)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
if (slot) {
|
|
||||||
mod = ModuleUtils.findModule('pv', 'v6');
|
|
||||||
ship.use(slot, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cargo === true) {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()))[0];
|
|
||||||
const mod = ModuleUtils.findInternal('cr', slot.maxClass, 'E');
|
|
||||||
ship.use(slot, mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refuelLimpets === true) {
|
|
||||||
const mod = ModuleUtils.findModule('fx', 'F4');
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
ship.use(mod, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repairLimpets === true) {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
let mod;
|
|
||||||
if (slot.maxClass >= 3) {
|
|
||||||
mod = ModuleUtils.findModule('rpl', '9e');
|
|
||||||
} else {
|
|
||||||
mod = ModuleUtils.findModule('rpl', '9s');
|
|
||||||
}
|
|
||||||
ship.use(mod, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prospector === true) {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
let mod;
|
|
||||||
if (slot.maxClass >= 3) {
|
|
||||||
mod = ModuleUtils.findModule('pc', 'P9');
|
|
||||||
} else {
|
|
||||||
mod = ModuleUtils.findModule('pc', 'P4');
|
|
||||||
}
|
|
||||||
ship.use(mod, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (collector === true) {
|
|
||||||
const slots = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()));
|
|
||||||
if (slots.length >= 2) {
|
|
||||||
let slot = slots.find(s => s.maxClass >= 5);
|
|
||||||
let mod;
|
|
||||||
if (slot) {
|
|
||||||
mod = ModuleUtils.findInternal('cc', slot.maxClass, 'D');
|
|
||||||
} else if (slots.find(s => s.maxClass <= 4)) {
|
|
||||||
slot = slots.find(s => s.maxClass <= 4);
|
|
||||||
mod = ModuleUtils.findInternal('cc', slot.maxClass, 'D');
|
|
||||||
}
|
|
||||||
ship.use(slot, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refinery === true) {
|
|
||||||
const slots = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 4)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
if (slots) {
|
|
||||||
const mod = ModuleUtils.findInternal('rf', 4, 'A');
|
|
||||||
ship.use(slots, mod);
|
|
||||||
} else {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass <= 3)
|
|
||||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()))[0];
|
|
||||||
const mod = ModuleUtils.findInternal('rf', slot.maxClass, 'A');
|
|
||||||
ship.use(slots, mod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dssPriority === 1) {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
|
||||||
const dss = ModuleUtils.findInternal('ss', 1, 'C')
|
|
||||||
if (slot) {
|
|
||||||
ship.use(slot, dss);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srvPriority === 1) {
|
|
||||||
const slot = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 2)
|
|
||||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()));
|
|
||||||
if (slot.find(s => s.maxClass >= 4)) {
|
|
||||||
const slot = slot.find(s => s.maxClass >= 4);
|
|
||||||
const srv = ModuleUtils.findInternal('pv', 4, 'G')
|
|
||||||
ship.use(slot, srv);
|
|
||||||
} else if (slot.find(s => s.maxClass >= 2)) {
|
|
||||||
const slot = slot.find(s => s.maxClass >= 2);
|
|
||||||
const srv = ModuleUtils.findInternal('pv', 2, 'G')
|
|
||||||
ship.use(slot, srv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gfsb === true) {
|
|
||||||
const slots = ship.internal.filter(s => !s.m)
|
|
||||||
.filter(s => s.maxClass >= 1)
|
|
||||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()));
|
|
||||||
if (slots.find(s => s.maxClass >= 5)) {
|
|
||||||
const mod = ModuleUtils.findInternal('gfsb', 5, 'H');
|
|
||||||
ship.use(slots.find(s => s.maxClass >= 5), mod)
|
|
||||||
} else if (slots.find(s => s.maxClass >= 4)) {
|
|
||||||
const mod = ModuleUtils.findInternal('gfsb', 4, 'H');
|
|
||||||
ship.use(slots.find(s => s.maxClass >= 4), mod)
|
|
||||||
} else if (slots.find(s => s.maxClass >= 3)) {
|
|
||||||
const mod = ModuleUtils.findInternal('gfsb', 3, 'H');
|
|
||||||
ship.use(slots.find(s => s.maxClass >= 3), mod)
|
|
||||||
} else if (slots.find(s => s.maxClass >= 2)) {
|
|
||||||
const mod = ModuleUtils.findInternal('gfsb', 2, 'H');
|
|
||||||
ship.use(slots.find(s => s.maxClass >= 2), mod)
|
|
||||||
} else if (slots.find(s => s.maxClass >= 1)) {
|
|
||||||
const mod = ModuleUtils.findInternal('gfsb', 1, 'H');
|
|
||||||
ship.use(slots.find(s => s.maxClass >= 1), mod)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// const pp = ship.getAvailableModules().lightestPowerPlant(Math.max(ship.powerRetracted, ship.powerDeployed), 'A');
|
|
||||||
// const t = ship.getAvailableModules().lightestThruster(ship.ladenMass);
|
|
||||||
// ship.use(ship.standard[0], pp);
|
|
||||||
// ship.use(ship.standard[1], t);
|
|
||||||
|
|
||||||
// ship.useLightestStandard(standardOpts);
|
|
||||||
ship.updatePowerGenerated()
|
|
||||||
.updatePowerUsed()
|
|
||||||
.recalculateMass()
|
|
||||||
.updateJumpStats()
|
|
||||||
.recalculateShield()
|
|
||||||
.recalculateShieldCells()
|
|
||||||
.recalculateArmour()
|
|
||||||
.recalculateDps()
|
|
||||||
.recalculateEps()
|
|
||||||
.recalculateHps()
|
|
||||||
.updateMovement()
|
|
||||||
.updateModificationsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trader Role
|
* Trader Role
|
||||||
* @param {Ship} ship Ship instance
|
* @param {Ship} ship Ship instance
|
||||||
@@ -609,7 +36,7 @@ export function trader(ship, shielded, standardOpts) {
|
|||||||
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||||
ship.useStandard('A')
|
ship.useStandard('A')
|
||||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
.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 Power Plant
|
.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[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
|
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')); // D Sensors
|
||||||
|
|
||||||
@@ -618,7 +45,7 @@ export function trader(ship, shielded, standardOpts) {
|
|||||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||||
.filter(a => a.maxClass >= sg.class)
|
.filter(a => a.maxClass >= sg.class)
|
||||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||||
shieldInternals.some(function (slot) {
|
shieldInternals.some(function(slot) {
|
||||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||||
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A');
|
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A');
|
||||||
if (shield && shield.maxmass > ship.hullMass) {
|
if (shield && shield.maxmass > ship.hullMass) {
|
||||||
@@ -660,11 +87,11 @@ export function trader(ship, shielded, standardOpts) {
|
|||||||
*/
|
*/
|
||||||
export function explorer(ship, planetary) {
|
export function explorer(ship, planetary) {
|
||||||
let standardOpts = { ppRating: 'A' },
|
let standardOpts = { ppRating: 'A' },
|
||||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||||
usedSlots = [],
|
usedSlots = [],
|
||||||
sgSlot,
|
sgSlot,
|
||||||
fuelScoopSlot,
|
fuelScoopSlot,
|
||||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||||
|
|
||||||
if (!planetary) { // Non-planetary explorers don't really need to boost
|
if (!planetary) { // Non-planetary explorers don't really need to boost
|
||||||
standardOpts.pd = '1D';
|
standardOpts.pd = '1D';
|
||||||
@@ -789,9 +216,9 @@ export function explorer(ship, planetary) {
|
|||||||
export function miner(ship, shielded) {
|
export function miner(ship, shielded) {
|
||||||
shielded = true;
|
shielded = true;
|
||||||
let standardOpts = { ppRating: 'A' },
|
let standardOpts = { ppRating: 'A' },
|
||||||
miningLaserCount = 2,
|
miningLaserCount = 2,
|
||||||
usedSlots = [],
|
usedSlots = [],
|
||||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||||
|
|
||||||
// Cargo hatch should be enabled
|
// Cargo hatch should be enabled
|
||||||
ship.setSlotEnabled(ship.cargoHatch, true);
|
ship.setSlotEnabled(ship.cargoHatch, true);
|
||||||
@@ -842,7 +269,7 @@ export function miner(ship, shielded) {
|
|||||||
|
|
||||||
// Dual mining lasers of highest possible class; remove anything else
|
// Dual mining lasers of highest possible class; remove anything else
|
||||||
const miningLaserOrder = [2, 3, 4, 1, 0];
|
const miningLaserOrder = [2, 3, 4, 1, 0];
|
||||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function (a, b) {
|
const miningLaserHardpoints = ship.hardpoints.concat().sort(function(a, b) {
|
||||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
|
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
|
||||||
});
|
});
|
||||||
for (let s of miningLaserHardpoints) {
|
for (let s of miningLaserHardpoints) {
|
||||||
@@ -856,7 +283,7 @@ export function miner(ship, shielded) {
|
|||||||
|
|
||||||
// Number of collector limpets required to be active is a function of the size of the ship and the power of the lasers
|
// 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)
|
const miningLaserDps = ship.hardpoints.filter(h => h.m != null)
|
||||||
.reduce(function (a, b) {
|
.reduce(function(a, b) {
|
||||||
return a + b.m.getDps();
|
return a + b.m.getDps();
|
||||||
}, 0);
|
}, 0);
|
||||||
// Find out how many internal slots we have, and their potential cargo size
|
// Find out how many internal slots we have, and their potential cargo size
|
||||||
@@ -887,7 +314,7 @@ export function miner(ship, shielded) {
|
|||||||
|
|
||||||
// Power distributor to power the mining lasers indefinitely
|
// Power distributor to power the mining lasers indefinitely
|
||||||
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
|
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
|
||||||
.reduce(function (a, b) {
|
.reduce(function(a, b) {
|
||||||
return a + b.m.getEps();
|
return a + b.m.getEps();
|
||||||
}, 0);
|
}, 0);
|
||||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
|
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
|
||||||
@@ -909,9 +336,9 @@ export function miner(ship, shielded) {
|
|||||||
*/
|
*/
|
||||||
export function racer(ship) {
|
export function racer(ship) {
|
||||||
let standardOpts = {},
|
let standardOpts = {},
|
||||||
usedSlots = [],
|
usedSlots = [],
|
||||||
sgSlot,
|
sgSlot,
|
||||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||||
|
|
||||||
// Cargo hatch can be disabled
|
// Cargo hatch can be disabled
|
||||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||||
|
|||||||
@@ -78,6 +78,5 @@ export const STATS_FORMATTING = {
|
|||||||
'thermres': { 'format': 'pct' },
|
'thermres': { 'format': 'pct' },
|
||||||
'wepcap': { 'format': 'round1', 'unit': 'MJ' },
|
'wepcap': { 'format': 'round1', 'unit': 'MJ' },
|
||||||
'weprate': { 'format': 'round1', 'unit': 'MW' },
|
'weprate': { 'format': 'round1', 'unit': 'MW' },
|
||||||
'jumpboost': { 'format': 'round1', 'unit': 'LY' },
|
'jumpboost': { 'format': 'round1', 'unit': 'LY' }
|
||||||
'proberadius': { 'format': 'pct1', 'unit': 'pct' },
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,417 +1,417 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Modifications } from 'coriolis-data/dist';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a tooltip with details of a blueprint's specials
|
* Generate a tooltip with details of a blueprint's specials
|
||||||
* @param {Object} translate The translate object
|
* @param {Object} translate The translate object
|
||||||
* @param {Object} blueprint The blueprint at the required grade
|
* @param {Object} blueprint The blueprint at the required grade
|
||||||
* @param {string} grp The group of the module
|
* @param {string} grp The group of the module
|
||||||
* @param {Object} m The module to compare with
|
* @param {Object} m The module to compare with
|
||||||
* @param {string} specialName The name of the special
|
* @param {string} specialName The name of the special
|
||||||
* @returns {Object} The react components
|
* @returns {Object} The react components
|
||||||
*/
|
*/
|
||||||
export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
||||||
const effects = [];
|
const effects = [];
|
||||||
if (!blueprint || !blueprint.features) {
|
if (!blueprint || !blueprint.features) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (m) {
|
if (m) {
|
||||||
// We also add in any benefits from specials that aren't covered above
|
// We also add in any benefits from specials that aren't covered above
|
||||||
if (m.blueprint) {
|
if (m.blueprint) {
|
||||||
for (const feature in Modifications.modifierActions[specialName]) {
|
for (const feature in Modifications.modifierActions[specialName]) {
|
||||||
// if (!blueprint.features[feature] && !m.mods.feature) {
|
// if (!blueprint.features[feature] && !m.mods.feature) {
|
||||||
const featureDef = Modifications.modifications[feature];
|
const featureDef = Modifications.modifications[feature];
|
||||||
if (featureDef && !featureDef.hidden) {
|
if (featureDef && !featureDef.hidden) {
|
||||||
let symbol = '';
|
let symbol = '';
|
||||||
if (feature === 'jitter') {
|
if (feature === 'jitter') {
|
||||||
symbol = '°';
|
symbol = '°';
|
||||||
} else if (featureDef.type === 'percentage') {
|
} else if (featureDef.type === 'percentage') {
|
||||||
symbol = '%';
|
symbol = '%';
|
||||||
}
|
}
|
||||||
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
||||||
if (featureDef.type === 'percentage') {
|
if (featureDef.type === 'percentage') {
|
||||||
current = Math.round(current / 10) / 10;
|
current = Math.round(current / 10) / 10;
|
||||||
} else if (featureDef.type === 'numeric') {
|
} else if (featureDef.type === 'numeric') {
|
||||||
current /= 100;
|
current /= 100;
|
||||||
}
|
}
|
||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
|
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature + '_specialTT'}>
|
<tr key={feature + '_specialTT'}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
||||||
style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<tbody>
|
<tbody>
|
||||||
{effects}
|
{effects}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a tooltip with details of a blueprint's effects
|
* Generate a tooltip with details of a blueprint's effects
|
||||||
* @param {Object} translate The translate object
|
* @param {Object} translate The translate object
|
||||||
* @param {Object} blueprint The blueprint at the required grade
|
* @param {Object} blueprint The blueprint at the required grade
|
||||||
* @param {Array} engineers The engineers supplying this blueprint
|
* @param {Array} engineers The engineers supplying this blueprint
|
||||||
* @param {string} grp The group of the module
|
* @param {string} grp The group of the module
|
||||||
* @param {Object} m The module to compare with
|
* @param {Object} m The module to compare with
|
||||||
* @returns {Object} The react components
|
* @returns {Object} The react components
|
||||||
*/
|
*/
|
||||||
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
||||||
const effects = [];
|
const effects = [];
|
||||||
if (!blueprint || !blueprint.features) {
|
if (!blueprint || !blueprint.features) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
for (const feature in blueprint.features) {
|
for (const feature in blueprint.features) {
|
||||||
const featureIsBeneficial = isBeneficial(feature, blueprint.features[feature]);
|
const featureIsBeneficial = isBeneficial(feature, blueprint.features[feature]);
|
||||||
const featureDef = Modifications.modifications[feature];
|
const featureDef = Modifications.modifications[feature];
|
||||||
if (!featureDef.hidden) {
|
if (!featureDef.hidden) {
|
||||||
let symbol = '';
|
let symbol = '';
|
||||||
if (feature === 'jitter') {
|
if (feature === 'jitter') {
|
||||||
symbol = '°';
|
symbol = '°';
|
||||||
} else if (featureDef.type === 'percentage') {
|
} else if (featureDef.type === 'percentage') {
|
||||||
symbol = '%';
|
symbol = '%';
|
||||||
}
|
}
|
||||||
let lowerBound = blueprint.features[feature][0];
|
let lowerBound = blueprint.features[feature][0];
|
||||||
let upperBound = blueprint.features[feature][1];
|
let upperBound = blueprint.features[feature][1];
|
||||||
if (featureDef.type === 'percentage') {
|
if (featureDef.type === 'percentage') {
|
||||||
lowerBound = Math.round(lowerBound * 1000) / 10;
|
lowerBound = Math.round(lowerBound * 1000) / 10;
|
||||||
upperBound = Math.round(upperBound * 1000) / 10;
|
upperBound = Math.round(upperBound * 1000) / 10;
|
||||||
}
|
}
|
||||||
const lowerIsBeneficial = isValueBeneficial(feature, lowerBound);
|
const lowerIsBeneficial = isValueBeneficial(feature, lowerBound);
|
||||||
const upperIsBeneficial = isValueBeneficial(feature, upperBound);
|
const upperIsBeneficial = isValueBeneficial(feature, upperBound);
|
||||||
if (m) {
|
if (m) {
|
||||||
// We have a module - add in the current value
|
// We have a module - add in the current value
|
||||||
let current = m.getModValue(feature);
|
let current = m.getModValue(feature);
|
||||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||||
current = Math.round(current / 10) / 10;
|
current = Math.round(current / 10) / 10;
|
||||||
} else if (featureDef.type === 'numeric') {
|
} else if (featureDef.type === 'numeric') {
|
||||||
current /= 100;
|
current /= 100;
|
||||||
}
|
}
|
||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// We do not have a module, no value
|
// We do not have a module, no value
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m) {
|
if (m) {
|
||||||
// Because we have a module add in any benefits that aren't part of the primary blueprint
|
// Because we have a module add in any benefits that aren't part of the primary blueprint
|
||||||
for (const feature in m.mods) {
|
for (const feature in m.mods) {
|
||||||
if (!blueprint.features[feature]) {
|
if (!blueprint.features[feature]) {
|
||||||
const featureDef = Modifications.modifications[feature];
|
const featureDef = Modifications.modifications[feature];
|
||||||
if (featureDef && !featureDef.hidden) {
|
if (featureDef && !featureDef.hidden) {
|
||||||
let symbol = '';
|
let symbol = '';
|
||||||
if (feature === 'jitter') {
|
if (feature === 'jitter') {
|
||||||
symbol = '°';
|
symbol = '°';
|
||||||
} else if (featureDef.type === 'percentage') {
|
} else if (featureDef.type === 'percentage') {
|
||||||
symbol = '%';
|
symbol = '%';
|
||||||
}
|
}
|
||||||
let current = m.getModValue(feature);
|
let current = m.getModValue(feature);
|
||||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||||
current = Math.round(current / 10) / 10;
|
current = Math.round(current / 10) / 10;
|
||||||
} else if (featureDef.type === 'numeric') {
|
} else if (featureDef.type === 'numeric') {
|
||||||
current /= 100;
|
current /= 100;
|
||||||
}
|
}
|
||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also add in any benefits from specials that aren't covered above
|
// We also add in any benefits from specials that aren't covered above
|
||||||
if (m.blueprint && m.blueprint.special) {
|
if (m.blueprint && m.blueprint.special) {
|
||||||
for (const feature in Modifications.modifierActions[m.blueprint.special.edname]) {
|
for (const feature in Modifications.modifierActions[m.blueprint.special.edname]) {
|
||||||
if (!blueprint.features[feature] && !m.mods.feature) {
|
if (!blueprint.features[feature] && !m.mods.feature) {
|
||||||
const featureDef = Modifications.modifications[feature];
|
const featureDef = Modifications.modifications[feature];
|
||||||
if (featureDef && !featureDef.hidden) {
|
if (featureDef && !featureDef.hidden) {
|
||||||
let symbol = '';
|
let symbol = '';
|
||||||
if (feature === 'jitter') {
|
if (feature === 'jitter') {
|
||||||
symbol = '°';
|
symbol = '°';
|
||||||
} else if (featureDef.type === 'percentage') {
|
} else if (featureDef.type === 'percentage') {
|
||||||
symbol = '%';
|
symbol = '%';
|
||||||
}
|
}
|
||||||
let current = m.getModValue(feature);
|
let current = m.getModValue(feature);
|
||||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||||
current = Math.round(current / 10) / 10;
|
current = Math.round(current / 10) / 10;
|
||||||
} else if (featureDef.type === 'numeric') {
|
} else if (featureDef.type === 'numeric') {
|
||||||
current /= 100;
|
current /= 100;
|
||||||
}
|
}
|
||||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||||
effects.push(
|
effects.push(
|
||||||
<tr key={feature}>
|
<tr key={feature}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let components;
|
let components;
|
||||||
if (!m) {
|
if (!m) {
|
||||||
components = [];
|
components = [];
|
||||||
for (const component in blueprint.components) {
|
for (const component in blueprint.components) {
|
||||||
components.push(
|
components.push(
|
||||||
<tr key={component}>
|
<tr key={component}>
|
||||||
<td style={{ textAlign: 'left' }}>{translate(component)}</td>
|
<td style={{ textAlign: 'left' }}>{translate(component)}</td>
|
||||||
<td style={{ textAlign: 'right' }}>{blueprint.components[component]}</td>
|
<td style={{ textAlign: 'right' }}>{blueprint.components[component]}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let engineersList;
|
let engineersList;
|
||||||
if (engineers) {
|
if (engineers) {
|
||||||
engineersList = [];
|
engineersList = [];
|
||||||
for (const engineer of engineers) {
|
for (const engineer of engineers) {
|
||||||
engineersList.push(
|
engineersList.push(
|
||||||
<tr key={engineer}>
|
<tr key={engineer}>
|
||||||
<td style={{ textAlign: 'left' }}>{engineer}</td>
|
<td style={{ textAlign: 'left' }}>{engineer}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<table width='100%'>
|
<table width='100%'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{translate('feature')}</td>
|
<td>{translate('feature')}</td>
|
||||||
<td>{translate('worst')}</td>
|
<td>{translate('worst')}</td>
|
||||||
{m ? <td>{translate('current')}</td> : null }
|
{m ? <td>{translate('current')}</td> : null }
|
||||||
<td>{translate('best')}</td>
|
<td>{translate('best')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{effects}
|
{effects}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{ components ? <table width='100%'>
|
{ components ? <table width='100%'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{translate('component')}</td>
|
<td>{translate('component')}</td>
|
||||||
<td>{translate('amount')}</td>
|
<td>{translate('amount')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{components}
|
{components}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table> : null }
|
</table> : null }
|
||||||
{ engineersList ? <table width='100%'>
|
{ engineersList ? <table width='100%'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{translate('engineers')}</td>
|
<td>{translate('engineers')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{engineersList}
|
{engineersList}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table> : null }
|
</table> : null }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this blueprint feature beneficial?
|
* Is this blueprint feature beneficial?
|
||||||
* @param {string} feature The name of the feature
|
* @param {string} feature The name of the feature
|
||||||
* @param {array} values The value of the feature
|
* @param {array} values The value of the feature
|
||||||
* @returns {boolean} True if this feature is beneficial
|
* @returns {boolean} True if this feature is beneficial
|
||||||
*/
|
*/
|
||||||
export function isBeneficial(feature, values) {
|
export function isBeneficial(feature, values) {
|
||||||
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
|
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
|
||||||
if (Modifications.modifications[feature].higherbetter) {
|
if (Modifications.modifications[feature].higherbetter) {
|
||||||
return !fact;
|
return !fact;
|
||||||
} else {
|
} else {
|
||||||
return fact;
|
return fact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this feature value beneficial?
|
* Is this feature value beneficial?
|
||||||
* @param {string} feature The name of the feature
|
* @param {string} feature The name of the feature
|
||||||
* @param {number} value The value of the feature
|
* @param {number} value The value of the feature
|
||||||
* @returns {boolean} True if this value is beneficial
|
* @returns {boolean} True if this value is beneficial
|
||||||
*/
|
*/
|
||||||
export function isValueBeneficial(feature, value) {
|
export function isValueBeneficial(feature, value) {
|
||||||
if (Modifications.modifications[feature].higherbetter) {
|
if (Modifications.modifications[feature].higherbetter) {
|
||||||
return value > 0;
|
return value > 0;
|
||||||
} else {
|
} else {
|
||||||
return value < 0;
|
return value < 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a blueprint with a given name and an optional module
|
* Get a blueprint with a given name and an optional module
|
||||||
* @param {string} name The name of the blueprint
|
* @param {string} name The name of the blueprint
|
||||||
* @param {Object} module The module for which to obtain this blueprint
|
* @param {Object} module The module for which to obtain this blueprint
|
||||||
* @returns {Object} The matching blueprint
|
* @returns {Object} The matching blueprint
|
||||||
*/
|
*/
|
||||||
export function getBlueprint(name, module) {
|
export function getBlueprint(name, module) {
|
||||||
// Start with a copy of the blueprint
|
// Start with a copy of the blueprint
|
||||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0);
|
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)];
|
const found = Modifications.blueprints[findMod(name)];
|
||||||
if (!found || !found.fdname) {
|
if (!found || !found.fdname) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const blueprint = JSON.parse(JSON.stringify(found));
|
const blueprint = JSON.parse(JSON.stringify(found));
|
||||||
return blueprint;
|
return blueprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide 'percent' primary modifications
|
* Provide 'percent' primary modifications
|
||||||
* @param {Object} ship The ship for which to perform the modifications
|
* @param {Object} ship The ship for which to perform the modifications
|
||||||
* @param {Object} m The module 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.
|
* @param {Number} percent The percent to set values to of full.
|
||||||
*/
|
*/
|
||||||
export function setPercent(ship, m, percent) {
|
export function setPercent(ship, m, percent) {
|
||||||
ship.clearModifications(m);
|
ship.clearModifications(m);
|
||||||
// Pick given value as multiplier
|
// Pick given value as multiplier
|
||||||
const mult = percent / 100;
|
const mult = percent / 100;
|
||||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||||
for (const featureName in features) {
|
for (const featureName in features) {
|
||||||
let value;
|
let value;
|
||||||
if (Modifications.modifications[featureName].higherbetter) {
|
if (Modifications.modifications[featureName].higherbetter) {
|
||||||
// Higher is better, but is this making it better or worse?
|
// Higher is better, but is this making it better or worse?
|
||||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||||
} else {
|
} else {
|
||||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Higher is worse, but is this making it better or worse?
|
// Higher is worse, but is this making it better or worse?
|
||||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||||
} else {
|
} else {
|
||||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_setValue(ship, m, featureName, value);
|
_setValue(ship, m, featureName, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide 'random' primary modifications
|
* Provide 'random' primary modifications
|
||||||
* @param {Object} ship The ship for which to perform the modifications
|
* @param {Object} ship The ship for which to perform the modifications
|
||||||
* @param {Object} m The module for which to perform the modifications
|
* @param {Object} m The module for which to perform the modifications
|
||||||
*/
|
*/
|
||||||
export function setRandom(ship, m) {
|
export function setRandom(ship, m) {
|
||||||
// Pick a single value for our randomness
|
// Pick a single value for our randomness
|
||||||
setPercent(ship, m, Math.random() * 100);
|
setPercent(ship, m, Math.random() * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a modification feature value
|
* Set a modification feature value
|
||||||
* @param {Object} ship The ship for which to perform the modifications
|
* @param {Object} ship The ship for which to perform the modifications
|
||||||
* @param {Object} m The module for which to perform the modifications
|
* @param {Object} m The module for which to perform the modifications
|
||||||
* @param {string} featureName The feature being set
|
* @param {string} featureName The feature being set
|
||||||
* @param {number} value The value being set for the feature
|
* @param {number} value The value being set for the feature
|
||||||
*/
|
*/
|
||||||
function _setValue(ship, m, featureName, value) {
|
function _setValue(ship, m, featureName, value) {
|
||||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||||
ship.setModification(m, featureName, value * 10000);
|
ship.setModification(m, featureName, value * 10000);
|
||||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||||
ship.setModification(m, featureName, value * 100);
|
ship.setModification(m, featureName, value * 100);
|
||||||
} else {
|
} else {
|
||||||
ship.setModification(m, featureName, value);
|
ship.setModification(m, featureName, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide 'percent' primary query
|
* Provide 'percent' primary query
|
||||||
* @param {Object} m The module for which to perform the query
|
* @param {Object} m The module for which to perform the query
|
||||||
* @returns {Number} percent The percentage indicator of current applied values.
|
* @returns {Number} percent The percentage indicator of current applied values.
|
||||||
*/
|
*/
|
||||||
export function getPercent(m) {
|
export function getPercent(m) {
|
||||||
let result = null;
|
let result = null;
|
||||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||||
for (const featureName in features) {
|
for (const featureName in features) {
|
||||||
if (features[featureName][0] === features[featureName][1]) {
|
if (features[featureName][0] === features[featureName][1]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = _getValue(m, featureName);
|
let value = _getValue(m, featureName);
|
||||||
let mult;
|
let mult;
|
||||||
if (featureName == 'shieldboost') {
|
if (featureName == 'shieldboost') {
|
||||||
mult = ((1 + value) * (1 + m.shieldboost)) - 1 - m.shieldboost;
|
mult = ((1 + value) * (1 + m.shieldboost)) - 1 - m.shieldboost;
|
||||||
} else if (Modifications.modifications[featureName].higherbetter) {
|
} else if (Modifications.modifications[featureName].higherbetter) {
|
||||||
// Higher is better, but is this making it better or worse?
|
// Higher is better, but is this making it better or worse?
|
||||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||||
} else {
|
} else {
|
||||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Higher is worse, but is this making it better or worse?
|
// Higher is worse, but is this making it better or worse?
|
||||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||||
} else {
|
} else {
|
||||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result && result != mult) {
|
if (result && result != mult) {
|
||||||
return null;
|
return null;
|
||||||
} else if (result != mult) {
|
} else if (result != mult) {
|
||||||
result = mult;
|
result = mult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query a feature value
|
* Query a feature value
|
||||||
* @param {Object} m The module for which to perform the query
|
* @param {Object} m The module for which to perform the query
|
||||||
* @param {string} featureName The feature being queried
|
* @param {string} featureName The feature being queried
|
||||||
* @returns {number} The value of the modification as a %
|
* @returns {number} The value of the modification as a %
|
||||||
*/
|
*/
|
||||||
function _getValue(m, featureName) {
|
function _getValue(m, featureName) {
|
||||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||||
return m.getModValue(featureName, true) / 10000;
|
return m.getModValue(featureName, true) / 10000;
|
||||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||||
return m.getModValue(featureName, true) / 100;
|
return m.getModValue(featureName, true) / 100;
|
||||||
} else {
|
} else {
|
||||||
return m.getModValue(featureName, true);
|
return m.getModValue(featureName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ tbody tr {
|
|||||||
background-color: @warning-bg;
|
background-color: @warning-bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(odd){
|
&.alt {
|
||||||
background-color: @alt-primary-bg;
|
background-color: @alt-primary-bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "https://coriolis.io/schemas/ship-loadout/1.json#",
|
"id": "https://coriolis.edcd.io/schemas/ship-loadout/1.json#",
|
||||||
"title": "Ship Loadout",
|
"title": "Ship Loadout",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
|
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "https://coriolis.io/schemas/ship-loadout/2.json#",
|
"id": "https://coriolis.edcd.io/schemas/ship-loadout/2.json#",
|
||||||
"title": "Ship Loadout",
|
"title": "Ship Loadout",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
|
"description": "The details for a specific ship build/loadout. DEPRECATED in favor of Version 3",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "https://coriolis.io/schemas/ship-loadout/3.json#",
|
"id": "https://coriolis.edcd.io/schemas/ship-loadout/3.json#",
|
||||||
"title": "Ship Loadout",
|
"title": "Ship Loadout",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "The details for a specific ship build/loadout",
|
"description": "The details for a specific ship build/loadout",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "https://coriolis.io/schemas/ship-loadout/4.json#",
|
"id": "https://coriolis.edcd.io/schemas/ship-loadout/4.json#",
|
||||||
"title": "Ship Loadout",
|
"title": "Ship Loadout",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "The details for a specific ship build/loadout",
|
"description": "The details for a specific ship build/loadout",
|
||||||
|
|||||||
@@ -8,13 +8,7 @@ if (workbox) {
|
|||||||
|
|
||||||
workbox.routing.registerRoute(
|
workbox.routing.registerRoute(
|
||||||
new RegExp('/(.*?)'),
|
new RegExp('/(.*?)'),
|
||||||
workbox.strategies.staleWhileRevalidate({
|
workbox.strategies.staleWhileRevalidate()
|
||||||
plugins: [
|
|
||||||
new workbox.cacheableResponse.Plugin({
|
|
||||||
statuses: [0, 200]
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
workbox.routing.registerRoute(
|
workbox.routing.registerRoute(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
entry: {
|
entry: {
|
||||||
main: './src/app/index.js',
|
main: './src/app/index.js'
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
// When requiring, you don't need to add these extensions
|
// When requiring, you don't need to add these extensions
|
||||||
@@ -22,11 +22,13 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: false,
|
minimize: false,
|
||||||
usedExports: true
|
splitChunks: {
|
||||||
|
chunks: 'all'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'build'),
|
path: path.join(__dirname, 'build'),
|
||||||
chunkFilename: '[name].bundle.js',
|
filename: 'app.js',
|
||||||
publicPath: '/'
|
publicPath: '/'
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -54,10 +56,7 @@ module.exports = {
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
|
{ 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: /\.less$/,
|
|
||||||
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!less-loader' })
|
|
||||||
},
|
|
||||||
{ test: /\.(js|jsx)$/, loaders: ['babel-loader'], include: path.join(__dirname, 'src') },
|
{ 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: /\.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: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||||
|
|||||||
@@ -11,28 +11,26 @@ const buildDate = new Date();
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
entry: {
|
entry: {
|
||||||
main: './src/app/index.js'
|
main: ['./src/app/index.js']
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.jsx', '.json', '.less']
|
extensions: ['.js', '.jsx', '.json', '.less']
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'build'),
|
path: path.join(__dirname, 'build'),
|
||||||
chunkFilename: '[name].bundle.js',
|
filename: '[name].[hash].js',
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
globalObject: 'this'
|
globalObject: 'this'
|
||||||
},
|
},
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: true,
|
minimize: true,
|
||||||
usedExports: true
|
splitChunks: {
|
||||||
|
chunks: 'all'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CopyWebpackPlugin(['src/.htaccess', { from: 'src/schemas', to: 'schemas' }, {
|
new CopyWebpackPlugin(['src/.htaccess', { from: 'src/schemas', to: 'schemas' }, {from: 'src/images/logo/*', flatten: true, to: ''}, 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']),
|
||||||
from: 'src/images/logo/*',
|
|
||||||
flatten: true,
|
|
||||||
to: ''
|
|
||||||
}, 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']),
|
|
||||||
// new webpack.optimize.CommonsChunkPlugin({
|
// new webpack.optimize.CommonsChunkPlugin({
|
||||||
// name: 'lib',
|
// name: 'lib',
|
||||||
// filename: 'lib.[chunkhash:6].js'
|
// filename: 'lib.[chunkhash:6].js'
|
||||||
@@ -50,15 +48,15 @@ module.exports = {
|
|||||||
disable: false,
|
disable: false,
|
||||||
allChunks: true
|
allChunks: true
|
||||||
}),
|
}),
|
||||||
// new BugsnagBuildReporterPlugin({
|
new BugsnagBuildReporterPlugin({
|
||||||
// apiKey: 'ba9fae819372850fb660755341fa6ef5',
|
apiKey: 'ba9fae819372850fb660755341fa6ef5',
|
||||||
// appVersion: `${pkgJson.version}-${buildDate.toISOString()}`
|
appVersion: `${pkgJson.version}-${buildDate.toISOString()}`
|
||||||
// }, { /* opts */ }),
|
}, { /* opts */ }),
|
||||||
// new BugsnagSourceMapUploaderPlugin({
|
new BugsnagSourceMapUploaderPlugin({
|
||||||
// apiKey: 'ba9fae819372850fb660755341fa6ef5',
|
apiKey: 'ba9fae819372850fb660755341fa6ef5',
|
||||||
// overwrite: true,
|
overwrite: true,
|
||||||
// appVersion: `${pkgJson.version}-${buildDate.toISOString()}`
|
appVersion: `${pkgJson.version}-${buildDate.toISOString()}`
|
||||||
// }),
|
}),
|
||||||
new InjectManifest({
|
new InjectManifest({
|
||||||
swSrc: './src/sw.js',
|
swSrc: './src/sw.js',
|
||||||
importWorkboxFrom: 'cdn',
|
importWorkboxFrom: 'cdn',
|
||||||
@@ -68,10 +66,7 @@ module.exports = {
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
|
{ 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: /\.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: /\.(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: /\.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: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
|
||||||
|
|||||||
Reference in New Issue
Block a user