diff --git a/src/app/Coriolis.jsx b/src/app/Coriolis.jsx index e7a84e8c..502a3ee7 100644 --- a/src/app/Coriolis.jsx +++ b/src/app/Coriolis.jsx @@ -324,44 +324,46 @@ export default class Coriolis extends React.Component { // Listen for appcache updated event, present refresh to update view // Check that service workers are registered if ('serviceWorker' in navigator) { - // Your service-worker.js *must* be located at the top-level directory relative to your site. - // It won't be able to control pages unless it's located at the same level or higher than them. - // *Don't* register service worker file in, e.g., a scripts/ sub-directory! - // See https://github.com/slightlyoff/ServiceWorker/issues/468 - const self = this; - navigator.serviceWorker.register('/service-worker.js').then(function(reg) { - // updatefound is fired if service-worker.js changes. - reg.onupdatefound = function() { - // The updatefound event implies that reg.installing is set; see - // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event - var installingWorker = reg.installing; + window.addEventListener('load', () => { + // Your service-worker.js *must* be located at the top-level directory relative to your site. + // It won't be able to control pages unless it's located at the same level or higher than them. + // *Don't* register service worker file in, e.g., a scripts/ sub-directory! + // See https://github.com/slightlyoff/ServiceWorker/issues/468 + const self = this; + navigator.serviceWorker.register('/service-worker.js').then(function(reg) { + // updatefound is fired if service-worker.js changes. + reg.onupdatefound = function() { + // The updatefound event implies that reg.installing is set; see + // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event + var installingWorker = reg.installing; - installingWorker.onstatechange = function() { - switch (installingWorker.state) { - case 'installed': - if (navigator.serviceWorker.controller) { - // At this point, the old content will have been purged and the fresh content will - // have been added to the cache. - // It's the perfect time to display a "New content is available; please refresh." - // message in the page's interface. - console.log('New or updated content is available.'); - self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache. - } else { - // At this point, everything has been precached. - // It's the perfect time to display a "Content is cached for offline use." message. - console.log('Content is now available offline!'); - self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache. - } - break; + installingWorker.onstatechange = function() { + switch (installingWorker.state) { + case 'installed': + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and the fresh content will + // have been added to the cache. + // It's the perfect time to display a "New content is available; please refresh." + // message in the page's interface. + console.log('New or updated content is available.'); + self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache. + } else { + // At this point, everything has been precached. + // It's the perfect time to display a "Content is cached for offline use." message. + console.log('Content is now available offline!'); + self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache. + } + break; - case 'redundant': - console.error('The installing service worker became redundant.'); - break; - } + case 'redundant': + console.error('The installing service worker became redundant.'); + break; + } + }; }; - }; - }).catch(function(e) { - console.error('Error during service worker registration:', e); + }).catch(function(e) { + console.error('Error during service worker registration:', e); + }); }); } window.onerror = this._onError.bind(this); diff --git a/src/app/i18n/ru.json b/src/app/i18n/ru.json index e92fde05..cb7584d8 100644 --- a/src/app/i18n/ru.json +++ b/src/app/i18n/ru.json @@ -20,11 +20,11 @@ "PHRASE_BLUEPRINT_BEST": "Лучшие основные значения для чертежа", "PHRASE_BLUEPRINT_EXTREME": "Лучшие положительные и худшие отрицательные основные значения для чертежа", "PHRASE_BLUEPRINT_RESET": "Убрать все изменения и чертёж", - "PHRASE_SELECT_SPECIAL": "Нажмите чтобы выбрать экспериментальный эффект", + "PHRASE_SELECT_SPECIAL": "Нажмите, чтобы выбрать экспериментальный эффект", "PHRASE_NO_SPECIAL": "Без экспериментального эффекта", - "PHRASE_SHOPPING_LIST": "Станции что продают эту сборку", - "PHRASE_REFIT_SHOPPING_LIST": "Станции что продают необходимые модули", - "PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон что может быть нанесён в каждым типе, если используются все щитонакопители", + "PHRASE_SHOPPING_LIST": "Станции, что продают эту сборку", + "PHRASE_REFIT_SHOPPING_LIST": "Станции, что продают необходимые модули", + "PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон, что может быть нанесён в каждым типе, если используются все щитонакопители", "PHRASE_TIME_TO_LOSE_SHIELDS": "Щиты продержатся", "PHRASE_TIME_TO_RECOVER_SHIELDS": "Щиты восстановятся за", "PHRASE_TIME_TO_RECHARGE_SHIELDS": "Щиты будут заряжены за", @@ -43,12 +43,12 @@ "PHRASE_TIME_TO_REMOVE_ARMOUR": "Снимет броню за", "TT_TIME_TO_REMOVE_ARMOUR": "Непрерывным огнём из всех орудий", "PHRASE_TIME_TO_DRAIN_WEP": "Опустошит ОРУЖ за", - "TT_TIME_TO_DRAIN_WEP": "Время за которое опустошится аккумулятор ОРУЖ при стрельбе из всех орудий", + "TT_TIME_TO_DRAIN_WEP": "Время, за которое опустошится аккумулятор ОРУЖ при стрельбе из всех орудий", "TT_TIME_TO_LOSE_SHIELDS": "Против поддерживаемой стрельбы из всех орудий противника", "TT_TIME_TO_LOSE_ARMOUR": "Против поддерживаемой стрельбы из всех орудий противника", - "TT_MODULE_ARMOUR": "Броня защищаюшае модули от урона", - "TT_MODULE_PROTECTION_EXTERNAL": "Процент урона перенаправленного от гнёзд на наборы для усиления модулей", - "TT_MODULE_PROTECTION_INTERNAL": "Процент урона перенаправленного от модулей вне гнёзд на наборы для усиления модулей", + "TT_MODULE_ARMOUR": "Броня, защищающая модули от урона", + "TT_MODULE_PROTECTION_EXTERNAL": "Процент урона, перенаправленного от гнёзд на наборы для усиления модулей", + "TT_MODULE_PROTECTION_INTERNAL": "Процент урона, перенаправленного от модулей вне гнёзд на наборы для усиления модулей", "TT_EFFECTIVE_SDPS_SHIELDS": "Реальный поддерживаемый ДПС пока аккумулятор ОРУЖ не пуст", "TT_EFFECTIVENESS_SHIELDS": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью без пунктов в СИС на 0 метрах", "TT_EFFECTIVE_SDPS_ARMOUR": "Реальный поддерживаемый ДПС пока аккумулятор ОРУЖ не пуст", @@ -56,7 +56,7 @@ "PHRASE_EFFECTIVE_SDPS_SHIELDS": "ПДПС против щитов", "PHRASE_EFFECTIVE_SDPS_ARMOUR": "ПДПС против брони", "TT_SUMMARY_SPEED": "С полным топливным баком и 4 пунктами в ДВИ", - "TT_SUMMARY_SPEED_NONFUNCTIONAL": "маневровые двигатели выключены или превышена максимальная масса с топливом и грузом", + "TT_SUMMARY_SPEED_NONFUNCTIONAL": "Маневровые двигатели выключены или превышена максимальная масса с топливом и грузом", "TT_SUMMARY_BOOST": "С полным топливным баком и 4 пунктами в ДВИ", "TT_SUMMARY_BOOST_NONFUNCTIONAL": "Распределитель питания не может обеспечить достаточно энергии для форсажа", "TT_SUMMARY_SHIELDS": "Чистая сила щита, включая усилители", @@ -68,16 +68,16 @@ "TT_SUMMARY_DPS": "Урон в секунду при стрельбе из всех орудий", "TT_SUMMARY_EPS": "Расход аккумулятора ОРУЖ в секунду при стрельбе из всех орудий", "TT_SUMMARY_TTD": "Время расхода аккумулятора ОРУЖ при стрельбе из всех орудий и с 4 пунктами в ОРУЖ", - "TT_SUMMARY_MAX_SINGLE_JUMP": "Самый дальний возможный прыжок без груза и с топливом достаточным только на сам прыжок", + "TT_SUMMARY_MAX_SINGLE_JUMP": "Самый дальний возможный прыжок без груза и с топливом, достаточным только на сам прыжок", "TT_SUMMARY_UNLADEN_SINGLE_JUMP": "Самый дальний возможный прыжок без груза и с полным топливным баком", "TT_SUMMARY_LADEN_SINGLE_JUMP": "Самый дальний возможный прыжок с полным грузовым отсеком и с полным топливным баком", "TT_SUMMARY_UNLADEN_TOTAL_JUMP": "Самая дальняя общая дистанция без груза, с полным топливным баком и при прыжках на максимальное расстояние", "TT_SUMMARY_LADEN_TOTAL_JUMP": "Самая дальняя общая дистанция с полным грузовым отсеком, с полным топливным баком и при прыжках на максимальное расстояние", - "HELP_MODIFICATIONS_MENU": "Ткните на номер чтобы ввести новое значение, или потяните вдоль полосы для малых изменений", + "HELP_MODIFICATIONS_MENU": "Нажмите на номер, чтобы ввести новое значение, или потяните вдоль полосы для малых изменений", "am": "Блок Автом. Полевого Ремонта", "bh": "Переборки", - "bl": "Пучковый Лазер", - "bsg": "Двухпоточный Щитогенератор", + "bl": "Пучковый лазер", + "bsg": "Двухпоточный щитогенератор", "c": "Орудие", "cc": "Контроллер магнитного снаряда для сбора", "ch": "Разбрасыватель дипольных отражателей", @@ -89,7 +89,7 @@ "fh": "Ангар для истребителя", "fi": "FSD-перехватчик", "fs": "Топливозаборник", - "fsd": "Рамочно Сместительный двигатель", + "fsd": "Рамочно-сместительный двигатель", "ft": "Топливный бак", "fx": "Контроллер магнитного снаряда для топлива", "hb": "Контроллер магнитного снаряда для взлома трюма", @@ -110,7 +110,7 @@ "pcm": "Каюта пассажира первого класса", "pcq": "Каюта пассажира класса люкс", "pd": "Распределитель питания", - "pl": "Ипмульсный лазер", + "pl": "Импульсный лазер", "po": "Точечная оборона", "pp": "Силовая установка", "psg": "Призматический щитогенератор", @@ -122,7 +122,7 @@ "sc": "Сканер обнаружения", "scb": "Щитонакопитель", "sg": "Щитогенератор", - "ss": "Сканер Поверхностей", + "ss": "Сканер поверхностей", "t": "Маневровые двигатели", "tp": "Торпедная стойка", "ul": "Пульсирующие лазеры", @@ -130,7 +130,7 @@ "emptyrestricted": "пусто (ограниченно)", "damage dealt to": "Урон нанесён", "damage received from": "Урон получен от", - "against shields": "Против шитов", + "against shields": "Против щитов", "against hull": "Против корпуса", "total effective shield": "Общие эффективные щиты", "ammunition": "Припасы", @@ -149,7 +149,7 @@ "eps": "Энергия в секунду", "epsseps": "Энергия в секунду (поддерживаемая энергия в секунду)", "hps": "Нагрев в секунду", - "hpsshps": "Heat per second (sustained heat per second)", + "hpsshps": "Нагрев в секунду (поддерживаемый нагрев в секунду)", "damage by": "Урон", "damage from": "Урон от", "shield cells": "Щитонакопители", @@ -183,7 +183,7 @@ "hullreinforcement": "Укрепление корпуса", "integrity": "Целостность", "jitter": "Дрожание", - "kinres": "Сопротивление китетическому урону", + "kinres": "Сопротивление кинетическому урону", "maxfuel": "Макс. топлива на прыжок", "mass": "Масса", "optmass": "Оптимизированная масса", @@ -381,4 +381,4 @@ "URL": "Ссылка", "WEP": "ОРУЖ", "yes": "Да" -} \ No newline at end of file +} diff --git a/src/app/shipyard/Calculations.js b/src/app/shipyard/Calculations.js index b7a2f22a..dd381127 100644 --- a/src/app/shipyard/Calculations.js +++ b/src/app/shipyard/Calculations.js @@ -544,7 +544,7 @@ export function calcBoost(ship) { if (!ship.boostEnergy || !ship.standard[4] || !ship.standard[4].m) { return undefined; } - return ship.boostEnergy / ship.standard[4].m.engrate; + return ship.boostEnergy / ship.standard[4].m.getEnginesRechargeRate(); } @@ -585,7 +585,7 @@ export function armourMetrics(ship) { hullThermDmg = hullThermDmg * (1 - slot.m.getThermalResistance()); hullCausDmg = hullCausDmg * (1 - slot.m.getCausticResistance()); } - if (slot.m && slot.m.grp == 'mrp') { + if (slot.m && (slot.m.grp == 'mrp' || slot.m.grp == 'gmrp')) { moduleArmour += slot.m.getIntegrity(); moduleProtection = moduleProtection * (1 - slot.m.getProtection()); } diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index ec242dd9..1019e4b5 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -172,10 +172,17 @@ export default class Module { if (result !== undefined) { if (modification.method === 'additive') { + // Resistance modding for hull reinforcement packages has additional + // diminishing returns implemented. The mod value gets lowered by + // the amount of base resistance the hrp has. + if (this.grp === 'hr' && + (name === 'kinres' || name === 'thermres' || name === 'explres')) { + modValue = modValue * (1 - result); + } result = result + modValue; } else if (modification.method === 'overwrite') { result = modValue; - } else if (name === 'shieldboost') { + } else if (name === 'shieldboost' || name === 'hullboost') { result = (1 + result) * (1 + modValue) - 1; } else { result = result * (1 + modValue); @@ -561,7 +568,8 @@ export default class Module { let result = 0; if (this['maxmass']) { result = this['maxmass']; - if (result && modified) { + // max mass is only modified for non-shield boosters + if (result && modified && this.grp !== 'sg') { let mult = this.getModValue('optmass') / 10000; if (mult) { result = result * (1 + mult); } } diff --git a/src/app/shipyard/Ship.js b/src/app/shipyard/Ship.js index 19bfdf64..87be0b90 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -937,7 +937,12 @@ export default class Ship { let epsChanged = n && n.getEps() || old && old.getEps(); let hpsChanged = n && n.getHps() || old && old.getHps(); - let armourChange = (slot === this.bulkheads) || (n && n.grp === 'hr') || (n && n.grp === 'ghrp') || (old && old.grp === 'hr') || (old && old.grp === 'ghrp') || (n && n.grp === 'mrp') || (old && old.grp === 'mrp') || (n && n.grp == 'mahr') || (old && old.grp == 'mahr'); + let armourChange = (slot === this.bulkheads) || + (n && n.grp === 'hr') || (old && old.grp === 'hr') || + (n && n.grp === 'ghrp') || (old && old.grp === 'ghrp') || + (n && n.grp == 'mahr') || (old && old.grp == 'mahr') || + (n && n.grp === 'mrp') || (old && old.grp === 'mrp') || + (n && n.grp === 'gmrp') || (old && old.grp == 'gmrp'); let shieldChange = (n && n.grp === 'bsg') || (old && old.grp === 'bsg') || (n && n.grp === 'psg') || (old && old.grp === 'psg') || (n && n.grp === 'sg') || (old && old.grp === 'sg') || (n && n.grp === 'sb') || (old && old.grp === 'sb') || (old && old.grp === 'gsrp') || (n && n.grp === 'gsrp');