mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Merge branch 'develop' into 'master'
This commit is contained in:
2
.docker/.dockerignore
Normal file
2
.docker/.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
37
.docker/Dockerfile
Normal file
37
.docker/Dockerfile
Normal file
@@ -0,0 +1,37 @@
|
||||
### STAGE 1: Build ###
|
||||
FROM node:9.11.1-alpine as builder
|
||||
ARG branch=develop
|
||||
ENV BRANCH=$branch
|
||||
WORKDIR /src/app
|
||||
RUN mkdir -p /src/app/coriolis
|
||||
RUN mkdir -p /src/app/coriolis-data
|
||||
|
||||
COPY ./coriolis/ /src/app/coriolis
|
||||
COPY ./coriolis-data/ /src/app/coriolis-data
|
||||
|
||||
RUN apk update
|
||||
RUN apk add git
|
||||
|
||||
RUN npm i -g npm
|
||||
|
||||
# Set up coriolis-data
|
||||
WORKDIR /src/app/coriolis-data
|
||||
RUN git fetch --all
|
||||
RUN git reset --hard origin/$BRANCH
|
||||
RUN npm install --no-package-lock
|
||||
RUN npm start
|
||||
|
||||
WORKDIR /src/app/coriolis
|
||||
RUN git fetch --all
|
||||
RUN git reset --hard origin/$BRANCH
|
||||
RUN npm install --no-package-lock
|
||||
RUN npm run build
|
||||
|
||||
|
||||
### STAGE 2: Production Environment ###
|
||||
FROM nginx:1.13.12-alpine as web
|
||||
COPY coriolis/.docker/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY --from=builder /src/app/coriolis/build /usr/share/nginx/html
|
||||
WORKDIR /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-c", "/etc/nginx/nginx.conf", "-g", "daemon off;"]
|
||||
35
.docker/docker-compose.yml
Normal file
35
.docker/docker-compose.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
version: '2.2'
|
||||
|
||||
services:
|
||||
coriolis_prod:
|
||||
image: edcd/coriolis:master
|
||||
restart: always
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
networks:
|
||||
- coriolis_web
|
||||
- default
|
||||
labels:
|
||||
- "traefik.docker.network=coriolis_coriolis_web"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.basic.frontend.rule=Host:coriolis.io,coriolis.edcd.io"
|
||||
- "traefik.basic.port=80"
|
||||
- "traefik.basic.protocol=http"
|
||||
|
||||
coriolis_dev:
|
||||
image: edcd/coriolis:develop
|
||||
restart: always
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
networks:
|
||||
- coriolis_web
|
||||
- default
|
||||
labels:
|
||||
- "traefik.docker.network=coriolis_coriolis_web"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.basic.frontend.rule=Host:beta.coriolis.io,beta.coriolis.edcd.io"
|
||||
- "traefik.basic.port=80"
|
||||
- "traefik.basic.protocol=http"
|
||||
|
||||
networks:
|
||||
coriolis_web:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
"clean": "rimraf build",
|
||||
"start": "node devServer.js",
|
||||
"lint": "eslint --ext .js,.jsx src",
|
||||
"preinstall": "ls ../coriolis-data || git clone https://github.com/edcd/coriolis-data.git ../coriolis-data && (cd ../coriolis-data && npm i)",
|
||||
"test": "jest",
|
||||
"prod-serve": "nginx -p $(pwd) -c nginx.conf",
|
||||
"prod-stop": "kill -QUIT $(cat nginx.pid)",
|
||||
|
||||
@@ -102,11 +102,11 @@ export default class Defence extends TranslatedComponent {
|
||||
|
||||
// Add effective shield from resistances
|
||||
const rawMj = shield.generator + shield.boosters + shield.cells;
|
||||
const explosiveMj = rawMj / (shield.explosive.generator * shield.explosive.boosters) - rawMj;
|
||||
const explosiveMj = rawMj / shield.explosive.total - rawMj;
|
||||
if (explosiveMj != 0) effectiveShieldExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(explosiveMj)}{units.MJ}</div>);
|
||||
const kineticMj = rawMj / (shield.kinetic.generator * shield.kinetic.boosters) - rawMj;
|
||||
const kineticMj = rawMj / shield.kinetic.total - rawMj;
|
||||
if (kineticMj != 0) effectiveShieldKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(kineticMj)}{units.MJ}</div>);
|
||||
const thermalMj = rawMj / (shield.thermal.generator * shield.thermal.boosters) - rawMj;
|
||||
const thermalMj = rawMj / shield.thermal.total - rawMj;
|
||||
if (thermalMj != 0) effectiveShieldThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(thermalMj)}{units.MJ}</div>);
|
||||
|
||||
// Add effective shield from power distributor SYS pips
|
||||
@@ -184,17 +184,17 @@ export default class Defence extends TranslatedComponent {
|
||||
const armourDamageTakenExplosiveTt = [];
|
||||
armourDamageTakenExplosiveTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.explosive.bulkheads)}</div>);
|
||||
armourDamageTakenExplosiveTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.explosive.reinforcement)}</div>);
|
||||
if (armour.explosive.bulkheads * armour.explosive.reinforcement != 1) effectiveArmourExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.explosive.bulkheads * armour.explosive.reinforcement) - rawArmour)}</div>);
|
||||
if (armour.explosive.total != 1) effectiveArmourExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / armour.explosive.total - rawArmour)}</div>);
|
||||
|
||||
const armourDamageTakenKineticTt = [];
|
||||
armourDamageTakenKineticTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.kinetic.bulkheads)}</div>);
|
||||
armourDamageTakenKineticTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.kinetic.reinforcement)}</div>);
|
||||
if (armour.kinetic.bulkheads * armour.kinetic.reinforcement != 1) effectiveArmourKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.kinetic.bulkheads * armour.kinetic.reinforcement) - rawArmour)}</div>);
|
||||
if (armour.kinetic.total != 1) effectiveArmourKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / armour.kinetic.total - rawArmour)}</div>);
|
||||
|
||||
const armourDamageTakenThermalTt = [];
|
||||
armourDamageTakenThermalTt.push(<div key='bulkheads'>{translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}</div>);
|
||||
armourDamageTakenThermalTt.push(<div key='reinforcement'>{translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}</div>);
|
||||
if (armour.thermal.bulkheads * armour.thermal.reinforcement != 1) effectiveArmourThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / (armour.thermal.bulkheads * armour.thermal.reinforcement) - rawArmour)}</div>);
|
||||
if (armour.thermal.total != 1) effectiveArmourThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(rawArmour / armour.thermal.total - rawArmour)}</div>);
|
||||
|
||||
const effectiveArmourData = [];
|
||||
const effectiveAbsoluteArmour = armour.total / armour.absolute.total;
|
||||
|
||||
@@ -79,7 +79,7 @@ export default class HardpointSlot extends Slot {
|
||||
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
|
||||
</div>
|
||||
<div className={'cb'}>
|
||||
{ m.getDps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'dpssdps' : 'dps')} onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}: {formats.round1(m.getDps())} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) })</span> : null }</div> : null }
|
||||
{ m.getDps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'dpssdps' : 'dps')} onMouseOut={tooltip.bind(null, null)}>{translate('DPS')}: {formats.round1(m.getDps())} { m.getClip() ? <span>({formats.round1(m.getSDps()) })</span> : null }</div> : null }
|
||||
{ m.getEps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'epsseps' : 'eps')} onMouseOut={tooltip.bind(null, null)}>{translate('EPS')}: {formats.round1(m.getEps())}{u.MW} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getEps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) }{u.MW})</span> : null }</div> : null }
|
||||
{ m.getHps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'hpsshps' : 'hps')} onMouseOut={tooltip.bind(null, null)}>{translate('HPS')}: {formats.round1(m.getHps())} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getHps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) })</span> : null }</div> : null }
|
||||
{ m.getDps() && m.getEps() ? <div className={'l'} onMouseOver={termtip.bind(null, 'dpe')} onMouseOut={tooltip.bind(null, null)}>{translate('DPE')}: {formats.f1(m.getDps() / m.getEps())}</div> : null }
|
||||
|
||||
@@ -397,11 +397,6 @@ export function shieldMetrics(ship, sys) {
|
||||
// res.kin = kinDim + overage;
|
||||
// boosterKinDmg = kinDim + overage;
|
||||
// }
|
||||
// Apply diminishing returns
|
||||
// boosterExplDmg = boosterExplDmg > 0.7 ? boosterExplDmg : 0.7 - (0.7 - boosterExplDmg) / 2;
|
||||
// boosterKinDmg = boosterKinDmg > 0.7 ? boosterKinDmg : 0.7 - (0.7 - boosterKinDmg) / 2;
|
||||
// boosterThermDmg = boosterThermDmg > 0.7 ? boosterThermDmg : 0.7 - (0.7 - boosterThermDmg) / 2;
|
||||
// res.therm = res.therm > 0.7 ? res.therm : 0.7 - (0.7 - res.therm) / 2;
|
||||
let shieldAddition = 0;
|
||||
if (ship) {
|
||||
for (const module of ship.internal) {
|
||||
@@ -485,31 +480,37 @@ export function shieldMetrics(ship, sys) {
|
||||
max: 1 - maxSysResistance
|
||||
};
|
||||
|
||||
let sgExplosiveDmg = 1 - shieldGenerator.getExplosiveResistance();
|
||||
let sgSbExplosiveDmg = diminishDamageMult(sgExplosiveDmg * 0.7, (1 - shieldGenerator.getExplosiveResistance()) * boosterExplDmg);
|
||||
shield.explosive = {
|
||||
generator: 1 - shieldGenerator.getExplosiveResistance(),
|
||||
boosters: boosterExplDmg,
|
||||
generator: sgExplosiveDmg,
|
||||
boosters: sgSbExplosiveDmg - sgExplosiveDmg,
|
||||
sys: (1 - sysResistance),
|
||||
total: (1 - shieldGenerator.getExplosiveResistance()) * boosterExplDmg * (1 - sysResistance),
|
||||
max: (1 - shieldGenerator.getExplosiveResistance()) * boosterExplDmg * (1 - maxSysResistance),
|
||||
res: 1 - boosterExplDmg
|
||||
total: sgSbExplosiveDmg * (1 - sysResistance),
|
||||
max: sgSbExplosiveDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbExplosiveDmg
|
||||
};
|
||||
|
||||
let sgKineticDmg = 1 - shieldGenerator.getKineticResistance();
|
||||
let sgSbKineticDmg = diminishDamageMult(sgKineticDmg * 0.7, (1 - shieldGenerator.getKineticResistance()) * boosterKinDmg);
|
||||
shield.kinetic = {
|
||||
generator: 1 - shieldGenerator.getKineticResistance(),
|
||||
boosters: boosterKinDmg,
|
||||
generator: sgKineticDmg,
|
||||
boosters: sgSbKineticDmg - sgKineticDmg,
|
||||
sys: (1 - sysResistance),
|
||||
total: (1 - shieldGenerator.getKineticResistance()) * boosterKinDmg * (1 - sysResistance),
|
||||
max: (1 - shieldGenerator.getKineticResistance()) * boosterKinDmg * (1 - maxSysResistance),
|
||||
res: 1 - boosterKinDmg
|
||||
total: sgSbKineticDmg * (1 - sysResistance),
|
||||
max: sgSbKineticDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbKineticDmg
|
||||
};
|
||||
|
||||
let sgThermalDmg = 1 - shieldGenerator.getThermalResistance();
|
||||
let sgSbThermalDmg = diminishDamageMult(sgThermalDmg * 0.7, (1 - shieldGenerator.getThermalResistance()) * boosterThermDmg);
|
||||
shield.thermal = {
|
||||
generator: 1 - shieldGenerator.getThermalResistance(),
|
||||
boosters: boosterThermDmg,
|
||||
generator: sgThermalDmg,
|
||||
boosters: sgSbThermalDmg - sgThermalDmg,
|
||||
sys: (1 - sysResistance),
|
||||
total: (1 - shieldGenerator.getThermalResistance()) * boosterThermDmg * (1 - sysResistance),
|
||||
max: (1 - shieldGenerator.getThermalResistance()) * boosterThermDmg * (1 - maxSysResistance),
|
||||
res: 1 - boosterThermDmg
|
||||
total: sgSbThermalDmg * (1 - sysResistance),
|
||||
max: sgSbThermalDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbThermalDmg
|
||||
};
|
||||
}
|
||||
return shield;
|
||||
@@ -545,22 +546,21 @@ export function armourMetrics(ship) {
|
||||
let hullKinDmg = 1;
|
||||
let hullThermDmg = 1;
|
||||
// const dimReturnLine = (res) => 1 - (1 - res) * 0.7;
|
||||
let res = {
|
||||
kin: 0,
|
||||
therm: 0,
|
||||
expl: 0
|
||||
};
|
||||
// let res = {
|
||||
// kin: 0,
|
||||
// therm: 0,
|
||||
// expl: 0
|
||||
// };
|
||||
// Armour from HRPs and module armour from MRPs
|
||||
for (let slot of ship.internal) {
|
||||
if (slot.m && (slot.m.grp === 'hr' || slot.m.grp === 'ghrp')) {
|
||||
armourReinforcement += slot.m.getHullReinforcement();
|
||||
// Hull boost for HRPs is applied against the ship's base armour
|
||||
armourReinforcement += ship.baseArmour * slot.m.getModValue('hullboost') / 10000;
|
||||
res.expl += slot.m.getExplosiveResistance();
|
||||
res.kin += slot.m.getKineticResistance();
|
||||
res.therm += slot.m.getThermalResistance();
|
||||
// res.expl += slot.m.getExplosiveResistance();
|
||||
// res.kin += slot.m.getKineticResistance();
|
||||
// res.therm += slot.m.getThermalResistance();
|
||||
hullExplDmg = hullExplDmg * (1 - slot.m.getExplosiveResistance());
|
||||
|
||||
hullKinDmg = hullKinDmg * (1 - slot.m.getKineticResistance());
|
||||
hullThermDmg = hullThermDmg * (1 - slot.m.getThermalResistance());
|
||||
}
|
||||
@@ -592,11 +592,6 @@ export function armourMetrics(ship) {
|
||||
// hullKinDmg = kinDim + overage;
|
||||
// }
|
||||
|
||||
// Apply diminishing returns
|
||||
// hullExplDmg = hullExplDmg > 0.7 ? hullExplDmg : 0.7 - (0.7 - hullExplDmg) / 2;
|
||||
// hullKinDmg = hullKinDmg > 0.7 ? hullKinDmg : 0.7 - (0.7 - hullKinDmg) / 2;
|
||||
// hullThermDmg = hullThermDmg > 0.7 ? hullThermDmg : 0.7 - (0.7 - hullThermDmg) / 2;
|
||||
|
||||
const armour = {
|
||||
bulkheads: armourBulkheads,
|
||||
reinforcement: armourReinforcement,
|
||||
@@ -613,25 +608,31 @@ export function armourMetrics(ship) {
|
||||
total: 1
|
||||
};
|
||||
|
||||
let armourExplDmg = diminishDamageMult(0.7, 1 - ship.bulkheads.m.getExplosiveResistance());
|
||||
let armourReinforcedExplDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getExplosiveResistance()) * hullExplDmg);
|
||||
armour.explosive = {
|
||||
bulkheads: 1 - ship.bulkheads.m.getExplosiveResistance(),
|
||||
reinforcement: hullExplDmg,
|
||||
total: (1 - ship.bulkheads.m.getExplosiveResistance()) * hullExplDmg,
|
||||
res: 1 - hullExplDmg
|
||||
bulkheads: armourExplDmg,
|
||||
reinforcement: armourReinforcedExplDmg - armourExplDmg,
|
||||
total: armourReinforcedExplDmg,
|
||||
res: 1 - armourReinforcedExplDmg
|
||||
};
|
||||
|
||||
let armourKinDmg = diminishDamageMult(0.7, 1 - ship.bulkheads.m.getKineticResistance());
|
||||
let armourReinforcedKinDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getKineticResistance()) * hullKinDmg);
|
||||
armour.kinetic = {
|
||||
bulkheads: 1 - ship.bulkheads.m.getKineticResistance(),
|
||||
reinforcement: hullKinDmg,
|
||||
total: (1 - ship.bulkheads.m.getKineticResistance()) * hullKinDmg,
|
||||
res: 1 - hullKinDmg
|
||||
bulkheads: armourKinDmg,
|
||||
reinforcement: armourReinforcedKinDmg - armourKinDmg,
|
||||
total: armourReinforcedKinDmg,
|
||||
res: 1 - armourReinforcedKinDmg
|
||||
};
|
||||
|
||||
let armourThermDmg = diminishDamageMult(0.7, 1 - ship.bulkheads.m.getThermalResistance());
|
||||
let armourReinforcedThermDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getThermalResistance()) * hullThermDmg);
|
||||
armour.thermal = {
|
||||
bulkheads: 1 - ship.bulkheads.m.getThermalResistance(),
|
||||
reinforcement: hullThermDmg,
|
||||
total: (1 - ship.bulkheads.m.getThermalResistance()) * hullThermDmg,
|
||||
res: 1 - hullThermDmg
|
||||
bulkheads: armourThermDmg,
|
||||
reinforcement: armourReinforcedThermDmg - armourThermDmg,
|
||||
total: armourReinforcedThermDmg,
|
||||
res: 1 - armourReinforcedThermDmg
|
||||
};
|
||||
return armour;
|
||||
}
|
||||
@@ -851,7 +852,7 @@ export function _weaponSustainedDps(m, opponent, opponentShields, opponentArmour
|
||||
weapon.eps = m.getClip() ? (m.getClip() * m.getEps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) : m.getEps();
|
||||
|
||||
// Initial sustained DPS
|
||||
let sDps = m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) : m.getDps();
|
||||
let sDps = m.getSDps();
|
||||
|
||||
// Take fall-off in to account
|
||||
const falloff = m.getFalloff();
|
||||
@@ -959,3 +960,17 @@ export function timeToDeplete(amount, dps, eps, capacity, recharge) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies diminishing returns to resistances.
|
||||
* @param {number} baseDamageMult The base resistance up to which no diminishing returns are applied.
|
||||
* @param {number} damageMult Resistance as damage multiplier
|
||||
* @returns {number} Actual damage multiplier
|
||||
*/
|
||||
export function diminishDamageMult(diminishFrom, damageMult) {
|
||||
if (damageMult > diminishFrom) {
|
||||
return damageMult;
|
||||
} else {
|
||||
return (diminishFrom / 2) + 0.5 * damageMult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,16 @@ export default class Module {
|
||||
if (modifierActions && modifierActions[name]) {
|
||||
// this special effect modifies our returned value
|
||||
const modification = Modifications.modifications[name];
|
||||
if (modification.method === 'additive') {
|
||||
const multiplier = modification.type === 'percentage' ? 10000 : 100;
|
||||
if (name === 'explres' || name === 'kinres' || name === 'thermres') {
|
||||
// Resistance modifications in itself are additive, however their
|
||||
// special effects are multiplicative. They affect the overall result
|
||||
// by (special effect resistance) * (damage mult after modification),
|
||||
// i. e. we need to apply the special effect as a multiplier to the
|
||||
// overall result and then calculate the difference.
|
||||
let baseMult = this[name] ? 1 - this[name] : 1;
|
||||
result = (baseMult - (baseMult - result / multiplier) * (1 - modifierActions[name] / 100)) * multiplier;
|
||||
} else if (modification.method === 'additive') {
|
||||
result = result + modifierActions[name] * 100;
|
||||
} else if (modification.method === 'overwrite') {
|
||||
result = modifierActions[name];
|
||||
@@ -59,7 +68,6 @@ export default class Module {
|
||||
} else {
|
||||
mod = modifierActions[name];
|
||||
}
|
||||
const multiplier = modification.type === 'percentage' ? 10000 : 100;
|
||||
result = (((1 + result / multiplier) * (1 + mod)) - 1) * multiplier;
|
||||
}
|
||||
}
|
||||
@@ -542,6 +550,27 @@ export default class Module {
|
||||
return damage * rpshot * rof;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SDPS for this module, taking into account modifications and special
|
||||
* effects.
|
||||
* @return {Number} The SDPS of this module
|
||||
*/
|
||||
getSDps() {
|
||||
let dps = this.getDps();
|
||||
if (this.getClip()) {
|
||||
let clipSize = this.getClip();
|
||||
// If auto-loader is applied, effective clip size will be nearly doubled
|
||||
// as you get one reload for every two shots fired.
|
||||
if (this.blueprint && this.blueprint.special && this.blueprint.special.edname === 'special_auto_loader') {
|
||||
clipSize += clipSize - 1;
|
||||
}
|
||||
let timeToDeplete = clipSize / this.getRoF();
|
||||
return dps * timeToDeplete / (timeToDeplete + this.getReload());
|
||||
} else {
|
||||
return dps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the EPS for this module, taking in to account modifications
|
||||
* @return {Number} the EPS of this module
|
||||
|
||||
@@ -996,25 +996,6 @@ export default class Ship {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate diminishing returns value, where values below a given limit are returned
|
||||
* as-is, and values between the lower and upper limit of the diminishing returns are
|
||||
* given at half value.
|
||||
* Commonly used for resistances.
|
||||
* @param {Number} val The value
|
||||
* @param {Number} drll The lower limit for diminishing returns
|
||||
* @param {Number} drul The upper limit for diminishing returns
|
||||
* @return {this} The ship instance (for chaining operations)
|
||||
*/
|
||||
diminishingReturns(val, drll, drul) {
|
||||
if (val < drll) {
|
||||
val = drll;
|
||||
} else if (val < drul) {
|
||||
val = drul - (drul - val) / 2;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate damage per second and related items for weapons
|
||||
* @return {this} The ship instance (for chaining operations)
|
||||
@@ -1306,45 +1287,14 @@ export default class Ship {
|
||||
*/
|
||||
recalculateArmour() {
|
||||
// Armour from bulkheads
|
||||
let bulkhead = this.bulkheads.m;
|
||||
let armour = this.baseArmour + (this.baseArmour * bulkhead.getHullBoost());
|
||||
let modulearmour = 0;
|
||||
let moduleprotection = 1;
|
||||
let hullExplRes = 1 - bulkhead.getExplosiveResistance();
|
||||
const hullExplResDRStart = hullExplRes * 0.7;
|
||||
const hullExplResDREnd = hullExplRes * 0;
|
||||
let hullKinRes = 1 - bulkhead.getKineticResistance();
|
||||
const hullKinResDRStart = hullKinRes * 0.7;
|
||||
const hullKinResDREnd = hullKinRes * 0;
|
||||
let hullThermRes = 1 - bulkhead.getThermalResistance();
|
||||
const hullThermResDRStart = hullThermRes * 0.7;
|
||||
const hullThermResDREnd = hullThermRes * 0;
|
||||
|
||||
// Armour from HRPs and module armour from MRPs
|
||||
for (let slot of this.internal) {
|
||||
if (slot.m && (slot.m.grp === 'hr' || slot.m.grp === 'ghrp')) {
|
||||
armour += slot.m.getHullReinforcement();
|
||||
// Hull boost for HRPs is applied against the ship's base armour
|
||||
armour += this.baseArmour * slot.m.getModValue('hullboost') / 10000;
|
||||
|
||||
hullExplRes *= (1 - slot.m.getExplosiveResistance());
|
||||
hullKinRes *= (1 - slot.m.getKineticResistance());
|
||||
hullThermRes *= (1 - slot.m.getThermalResistance());
|
||||
}
|
||||
if (slot.m && slot.m.grp == 'mrp') {
|
||||
modulearmour += slot.m.getIntegrity();
|
||||
moduleprotection = moduleprotection * (1 - slot.m.getProtection());
|
||||
}
|
||||
}
|
||||
moduleprotection = 1 - moduleprotection;
|
||||
|
||||
this.armour = armour;
|
||||
this.modulearmour = modulearmour;
|
||||
this.moduleprotection = moduleprotection;
|
||||
this.hullExplRes = 1 - this.diminishingReturns(hullExplRes, hullExplResDREnd, hullExplResDRStart);
|
||||
this.hullKinRes = 1 - this.diminishingReturns(hullKinRes, hullKinResDREnd, hullKinResDRStart);
|
||||
this.hullThermRes = 1 - this.diminishingReturns(hullThermRes, hullThermResDREnd, hullThermResDRStart);
|
||||
let metrics = Calc.armourMetrics(this);
|
||||
|
||||
this.armour = metrics.total ? metrics.total : 0;
|
||||
this.modulearmour = metrics.modulearmour;
|
||||
this.moduleprotection = metrics.moduleprotection;
|
||||
this.hullExplRes = 1 - metrics.explosive.total;
|
||||
this.hullKinRes = 1 - metrics.kinetic.total;
|
||||
this.hullThermRes = 1 - metrics.thermal.total;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user