mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee52a4b716 | ||
|
|
a14974fef4 | ||
|
|
2c0959d68b | ||
|
|
0221d05b04 | ||
|
|
975432b45a | ||
|
|
e78551f5d9 | ||
|
|
b1daf6f799 | ||
|
|
df03102c35 | ||
|
|
e7d1a0df63 | ||
|
|
ca0c9675b3 | ||
|
|
491899fe49 | ||
|
|
cc22a89ad6 | ||
|
|
d389114189 | ||
|
|
9d0f7a166b | ||
|
|
c344d56d48 | ||
|
|
eb5d0e868c | ||
|
|
c28f22a78b | ||
|
|
e2b22dd4ca | ||
|
|
f5ecccec48 | ||
|
|
7c8eee4707 | ||
|
|
99e251fd4b | ||
|
|
c1ddecfd3e | ||
|
|
0ae59c5e48 | ||
|
|
eb76040b08 | ||
|
|
7698cb75e9 | ||
|
|
bd7139c703 | ||
|
|
c9b9404ba1 | ||
|
|
84ff013a9e | ||
|
|
d2bcf6cd71 | ||
|
|
e52c6730f4 | ||
|
|
e448b3cb0a | ||
|
|
705f3158aa | ||
|
|
f4789717fe | ||
|
|
93e69f215b | ||
|
|
d04e662de4 | ||
|
|
a9f9285278 | ||
|
|
c5e27d43aa | ||
|
|
db376829f5 | ||
|
|
79a31fd992 | ||
|
|
094f3aa3e2 | ||
|
|
41d51743d3 | ||
|
|
cf741d18ed |
19
ChangeLog.md
19
ChangeLog.md
@@ -1,3 +1,22 @@
|
|||||||
|
#2.2.13
|
||||||
|
* Add 'time to drain' summary value. This is the time to drain the WEP capacitor if firing all enabled weapons
|
||||||
|
* Do not include utility slot DPS/EPS/HPS in summary information
|
||||||
|
* Ensure that auto loader special shows in the tooltip
|
||||||
|
* Ensure that ship mass is recalculated when appropriate
|
||||||
|
* Use coriolis-data 2.2.13:
|
||||||
|
* Add plasma slug special effect for plasma accelerator
|
||||||
|
* Tweak hull costs of ships
|
||||||
|
|
||||||
|
#2.2.12
|
||||||
|
* Tidy up old references to coriolis.io
|
||||||
|
* Add ability to add and remove special effects to weapon modifications
|
||||||
|
* Add weapon engineering information to Damage Dealt section
|
||||||
|
* Change shortcut for link from ctrl-l to ctrl-o to avoid clash with location bar
|
||||||
|
* Only show one of power generation or draw in tooltips, according to module
|
||||||
|
* Use coriolis-data 2.2.12:
|
||||||
|
* Add special effects for each blueprint
|
||||||
|
* Add IDs for most Powerplay modules
|
||||||
|
|
||||||
#2.2.11
|
#2.2.11
|
||||||
* Add help system and initial help file
|
* Add help system and initial help file
|
||||||
* Make absolute damage visible
|
* Make absolute damage visible
|
||||||
|
|||||||
@@ -269,20 +269,19 @@
|
|||||||
"topSpeed": 187.01,
|
"topSpeed": 187.01,
|
||||||
"totalCost": 882362058,
|
"totalCost": 882362058,
|
||||||
"totalDpe": 142.68,
|
"totalDpe": 142.68,
|
||||||
"totalDps": 103.8,
|
"totalDps": 101.13,
|
||||||
"totalEps": 22.71,
|
"totalEps": 18.71,
|
||||||
"totalHps": 677.29,
|
|
||||||
"totalExplDpe": 0,
|
"totalExplDpe": 0,
|
||||||
"totalExplDps": 0,
|
"totalExplDps": 0,
|
||||||
"totalExplSDps": 0,
|
"totalExplSDps": 0,
|
||||||
"totalAbsDpe": 3.57,
|
"totalAbsDpe": 3.57,
|
||||||
"totalAbsDps": 18.78,
|
"totalAbsDps": 18.78,
|
||||||
"totalAbsSDps": 14.45,
|
"totalAbsSDps": 14.45,
|
||||||
"totalHps": 33.62,
|
"totalHps": 28.28,
|
||||||
"totalKinDpe": 117.48,
|
"totalKinDpe": 117.48,
|
||||||
"totalKinDps": 24.94,
|
"totalKinDps": 22.27,
|
||||||
"totalKinSDps": 18.76,
|
"totalKinSDps": 16.91,
|
||||||
"totalSDps": 91.84,
|
"totalSDps": 89.99,
|
||||||
"totalThermDpe": 21.63,
|
"totalThermDpe": 21.63,
|
||||||
"totalThermDps": 60.08,
|
"totalThermDps": 60.08,
|
||||||
"totalThermSDps": 58.64,
|
"totalThermSDps": 58.64,
|
||||||
@@ -320,6 +319,7 @@
|
|||||||
"shieldCells": 1840,
|
"shieldCells": 1840,
|
||||||
"shieldExplRes": 0.5,
|
"shieldExplRes": 0.5,
|
||||||
"shieldKinRes": 0.4,
|
"shieldKinRes": 0.4,
|
||||||
"shieldThermRes": -0.2
|
"shieldThermRes": -0.2,
|
||||||
|
"timeToDrain": 7.04
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=A2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifr--v66g2f.AwRj4zNaqA%3D%3D.CwRgDBldUExuBiIlUA%3D%3D.H4sIAAAAAAAAA02Svy9DURTHT1vvtfoat32eekVV9fm1kBgwSIw0YWYgBqmpMZkMBomFVfwFEoZKhBjE1qWTgegiDX%2BCQdKI1j2%2BR%2FJ4yzfnvu%2FnfO%2B979yQXiCi7xAkbRpEqsLMsRKWHNZpsSKQnppJVLAdIvc6DGiwxexMaWb7GDZHdJ%2BQaCf71Ia%2F88XsOp1EThk9bOh5P2kkahGN3qPM1wANbyOk87zNHH%2FBUs0gnWN61T9TOwfJ7EWJjMcms1lEo30Gx11BD8f1mh%2FcTkCMMvY0HZcoe4Wk5By%2BFcrrRL0N0OOlrd0Ntv57jGoc%2BH4%2F8EqHj3%2FCUXc4FicC5NFvsJBVIWeFvESlpuXSuCS5RRyLlV70z%2B4uQaw6ypSIJ6KOJDgZgFpQ60YgEU9EPQmUCkAfAj0IJOKJqC4wuYMY9rQD5CuubT0LSag8qdShxHUHoElcyWrAT4l4IsoCw65e%2BRv5BqKtC0mSJu8LH8OFT%2Bb%2BE8SZb0CcEn4AZ3TRDx5q4l1EJ%2BCP1bEM1WSaAwH%2FFkOLPoofwTo0LY8nr7O%2B37cp4yWIu4zHlHiXGfMPmat5gqMCAAA%3D&bn=Imported%20Federal%20Corvette');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=A2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifr--v66g2f.AwRj4zNaqA%3D%3D.CwRgDBldUExuBiIlUA%3D%3D.H4sIAAAAAAAAA02SPy9DURjG3%2F65vW1v47TXVbeqqF7EQtIIBomRJswsYmISH8BgkFhqFZ9AwlALMYitkXQyEF2k4SMYJNK0dV7PK7nc5ck55%2Fm9z%2FnznpBeJqLvECQbM4hUjZnjO5hyWGfFikAGGjGiku0QuddhQCNdZmdWM9snsDmih4REOdlnNvz9DrPrJIicPdSwoZf8pAnTIpq8x7DYADS%2Bi5DERY85%2BYqpmkc6x%2FWGf6beKCR3YBIZFZCxCgrtczjuOmo4qTf94F4KYuxhz5jjEhXmUJNexFrpIUo02ALN1j9u1JMgD%2FMga1GfbMNRd9iHUwGy%2BpspZF3IBSGvMFJluS%2FuR24FJ2KlV%2Fxju6sQq4lhRsQTUVUJTgegLtS6EUjEE1HPAmUC0KdAjwKJeCKqD8zoURx72gHyDW9nvQhJGHkyUscS1x%2BAZnAlqwU%2FI%2BKJKEvextXrf93eQrR1KUlS5HWwGC61mfOn0oN3IM4OHoBzuuIHj33hS5jT8KeamIYa0sjhgH%2BLfplP4kcwD5Xl3xR1wfeHtqWzBHHX8I9SH9Je%2FgGvXxeungIAAA%3D%3D&bn=Imported%20Federal%20Corvette');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports a valid v4 build', function() {
|
it('imports a valid v4 build', function() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "coriolis_shipyard",
|
"name": "coriolis_shipyard",
|
||||||
"version": "2.2.11",
|
"version": "2.2.13",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EDCD/coriolis"
|
"url": "https://github.com/EDCD/coriolis"
|
||||||
|
|||||||
@@ -174,11 +174,12 @@ export default class Coriolis extends React.Component {
|
|||||||
this._showModal(<ModalImport />);
|
this._showModal(<ModalImport />);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 76: // 'l'
|
case 79: // 'o'
|
||||||
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + l
|
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + o
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._showModal(<ModalPermalink url={window.location.href}/>);
|
this._showModal(<ModalPermalink url={window.location.href}/>);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case 83: // 's'
|
case 83: // 's'
|
||||||
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + s
|
if (e.ctrlKey || e.metaKey) { // CTRL/CMD + s
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
* @return {boolean} Returns the per-weapon damage
|
* @return {boolean} Returns the per-weapon damage
|
||||||
*/
|
*/
|
||||||
_calcWeapons(ship, against, range) {
|
_calcWeapons(ship, against, range) {
|
||||||
|
const translate = this.context.language.translate;
|
||||||
|
|
||||||
// Tidy up the range so that it's to 4 decimal places
|
// Tidy up the range so that it's to 4 decimal places
|
||||||
range = Math.round(10000 * range) / 10000;
|
range = Math.round(10000 * range) / 10000;
|
||||||
|
|
||||||
@@ -137,22 +139,31 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`;
|
||||||
|
let engineering;
|
||||||
|
if (m.blueprint && m.blueprint.name) {
|
||||||
|
engineering = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
|
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
||||||
|
engineering += ', ' + translate(m.blueprint.special.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
const effectivenessShields = dropoff;
|
const effectivenessShields = dropoff;
|
||||||
const effectiveDpsShields = m.getDps() * effectivenessShields * dropoff;
|
const effectiveDpsShields = m.getDps() * effectivenessShields;
|
||||||
const effectiveSDpsShields = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessShields : effectiveDpsShields) * dropoff;
|
const effectiveSDpsShields = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessShields : effectiveDpsShields);
|
||||||
const effectivenessHull = (m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness) * dropoff;
|
const effectivenessHull = (m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness) * dropoff;
|
||||||
const effectiveDpsHull = m.getDps() * effectivenessHull * dropoff;
|
const effectiveDpsHull = m.getDps() * effectivenessHull;
|
||||||
const effectiveSDpsHull = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessHull : effectiveDpsHull) * dropoff;
|
const effectiveSDpsHull = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectivenessHull : effectiveDpsHull);
|
||||||
totals.effectiveDpsShields += effectiveDpsShields;
|
totals.effectiveDpsShields += effectiveDpsShields;
|
||||||
totals.effectiveSDpsShields += effectiveSDpsShields;
|
totals.effectiveSDpsShields += effectiveSDpsShields;
|
||||||
totals.effectiveDpsHull += effectiveDpsHull;
|
totals.effectiveDpsHull += effectiveDpsHull;
|
||||||
totals.effectiveSDpsHull += effectiveSDpsHull;
|
totals.effectiveSDpsHull += effectiveSDpsHull;
|
||||||
totalDps += m.getDps();
|
totalDps += m.getDps();
|
||||||
|
|
||||||
|
|
||||||
weapons.push({ id: i,
|
weapons.push({ id: i,
|
||||||
mount: m.mount,
|
mount: m.mount,
|
||||||
name: m.name || m.grp,
|
name: m.name || m.grp,
|
||||||
classRating,
|
classRating,
|
||||||
|
engineering,
|
||||||
effectiveDpsShields,
|
effectiveDpsShields,
|
||||||
effectiveSDpsShields,
|
effectiveSDpsShields,
|
||||||
effectivenessShields,
|
effectivenessShields,
|
||||||
@@ -246,6 +257,7 @@ export default class DamageDealt extends TranslatedComponent {
|
|||||||
{weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null}
|
{weapon.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : null}
|
||||||
{weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
|
{weapon.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : null}
|
||||||
{weapon.classRating} {translate(weapon.name)}
|
{weapon.classRating} {translate(weapon.name)}
|
||||||
|
{weapon.engineering ? ' (' + weapon.engineering + ')' : null }
|
||||||
</td>
|
</td>
|
||||||
<td className='ri'>{formats.round1(weapon.effectiveDpsShields)}</td>
|
<td className='ri'>{formats.round1(weapon.effectiveDpsShields)}</td>
|
||||||
<td className='ri'>{formats.round1(weapon.effectiveSDpsShields)}</td>
|
<td className='ri'>{formats.round1(weapon.effectiveSDpsShields)}</td>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export default class HardpointSlot extends Slot {
|
|||||||
let modTT = translate('modified');
|
let modTT = translate('modified');
|
||||||
if (m && m.blueprint && m.blueprint.name) {
|
if (m && m.blueprint && m.blueprint.name) {
|
||||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
if (m.blueprint.special && m.blueprint.special.id) {
|
if (m.blueprint.special && m.blueprint.special.id >= 0) {
|
||||||
modTT += ', ' + translate(m.blueprint.special.name);
|
modTT += ', ' + translate(m.blueprint.special.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ export default class InternalSlot extends Slot {
|
|||||||
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
||||||
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.gen(m.getAmmo())}</div> : null }
|
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.gen(m.getAmmo())}</div> : null }
|
||||||
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
||||||
{ m.shieldreinforcement ? <div className={'l'}>{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} <u>MJ</u> {translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}</div> : null }
|
{ m.getShieldReinforcement() ? <div className={'l'}>{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} <u>MJ</u> {translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}</div> : null }
|
||||||
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
|
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
|
||||||
{ m.getFacingLimit() ? <div className={'l'}>{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°</div> : null }
|
{ m.getFacingLimit() ? <div className={'l'}>{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°</div> : null }
|
||||||
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f2(m.getRange())}{u.km}</div> : null }
|
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f2(m.getRange())}{u.km}</div> : null }
|
||||||
{ m.getRangeT() ? <div className={'l'}>{translate('ranget')} {formats.f1(m.getRangeT())}{u.s}</div> : null }
|
{ m.getRangeT() ? <div className={'l'}>{translate('ranget')} {formats.f1(m.getRangeT())}{u.s}</div> : null }
|
||||||
{ m.spinup ? <div className={'l'}>{translate('spinup')}: {formats.f1(m.spinup)}{u.s}</div> : null }
|
{ m.getSpinup() ? <div className={'l'}>{translate('spinup')}: {formats.f1(m.getSpinup())}{u.s}</div> : null }
|
||||||
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null }
|
{ m.getTime() ? <div className={'l'}>{translate('time')}: {formats.time(m.getTime())}</div> : null }
|
||||||
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
|
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
|
||||||
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
|
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
|
||||||
{ m.rangeLS === null ? <div className={'l'}>∞{u.Ls}</div> : null }
|
{ m.rangeLS === null ? <div className={'l'}>∞{u.Ls}</div> : null }
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default class Modification extends TranslatedComponent {
|
|||||||
|
|
||||||
let m = this.props.m;
|
let m = this.props.m;
|
||||||
let ship = this.props.ship;
|
let ship = this.props.ship;
|
||||||
ship.setModification(m, name, scaledValue);
|
ship.setModification(m, name, scaledValue, true);
|
||||||
|
|
||||||
this.setState({ value });
|
this.setState({ value });
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
this.state = this._initState(props, context);
|
this.state = this._initState(props, context);
|
||||||
|
|
||||||
this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this);
|
this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this);
|
||||||
|
this._toggleSpecialsMenu = this._toggleSpecialsMenu.bind(this);
|
||||||
this._rollWorst = this._rollWorst.bind(this);
|
this._rollWorst = this._rollWorst.bind(this);
|
||||||
this._rollRandom = this._rollRandom.bind(this);
|
this._rollRandom = this._rollRandom.bind(this);
|
||||||
this._rollAverage = this._rollAverage.bind(this);
|
this._rollAverage = this._rollAverage.bind(this);
|
||||||
@@ -44,13 +45,27 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
*/
|
*/
|
||||||
_initState(props, context) {
|
_initState(props, context) {
|
||||||
let { m, onChange, ship } = props;
|
let { m, onChange, ship } = props;
|
||||||
|
const { language, tooltip, termtip } = context;
|
||||||
|
const translate = language.translate;
|
||||||
|
|
||||||
|
// Set up the blueprints
|
||||||
let blueprints = [];
|
let blueprints = [];
|
||||||
for (const blueprintName in Modifications.modules[m.grp].blueprints) {
|
for (const blueprintName in Modifications.modules[m.grp].blueprints) {
|
||||||
for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) {
|
for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) {
|
||||||
const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade);
|
const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade);
|
||||||
const key = blueprintName + ':' + grade;
|
const key = blueprintName + ':' + grade;
|
||||||
blueprints.push(<div style={{ cursor: 'pointer' }} key={ key } onClick={ close }>{Modifications.blueprints[blueprintName].name} grade {grade}</div>);
|
blueprints.push(<div style={{ cursor: 'pointer' }} key={ key } onClick={ close }>{translate(Modifications.blueprints[blueprintName].name + ' grade ' + grade)}</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the special effects
|
||||||
|
let specials = [];
|
||||||
|
if (Modifications.modules[m.grp].specials && Modifications.modules[m.grp].specials.length > 0) {
|
||||||
|
const close = this._specialSelected.bind(this, null);
|
||||||
|
specials.push(<div style={{ cursor: 'pointer' }} key={ 'none' } onClick={ close }>{translate('PHRASE_NO_SPECIAL')}</div>);
|
||||||
|
for (const specialName of Modifications.modules[m.grp].specials) {
|
||||||
|
const close = this._specialSelected.bind(this, specialName);
|
||||||
|
specials.push(<div style={{ cursor: 'pointer' }} key={ specialName } onClick={ close }>{translate(Modifications.specials[specialName].name)}</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +73,9 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
const modifications = this._setModifications(props);
|
const modifications = this._setModifications(props);
|
||||||
|
|
||||||
const blueprintMenuOpened = false;
|
const blueprintMenuOpened = false;
|
||||||
|
const specialMenuOpened = false;
|
||||||
|
|
||||||
// Set up the specials for this module
|
return { blueprintMenuOpened, blueprints, modifications, specialMenuOpened, specials };
|
||||||
// const specials = _selectSpecials(m);
|
|
||||||
|
|
||||||
return { blueprintMenuOpened, blueprints, modifications };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,6 +119,34 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the specials menu
|
||||||
|
*/
|
||||||
|
_toggleSpecialsMenu() {
|
||||||
|
const specialMenuOpened = !this.state.specialMenuOpened;
|
||||||
|
this.setState({ specialMenuOpened });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activated when a special is selected
|
||||||
|
* @param {int} special The name of the selected special
|
||||||
|
*/
|
||||||
|
_specialSelected(special) {
|
||||||
|
const { m } = this.props;
|
||||||
|
|
||||||
|
if (m.blueprint) {
|
||||||
|
if (special === null) {
|
||||||
|
m.blueprint.special = null;
|
||||||
|
} else {
|
||||||
|
m.blueprint.special = Modifications.specials[special];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const specialMenuOpened = false;
|
||||||
|
this.setState({ specialMenuOpened, modifications: this._setModifications(this.props) });
|
||||||
|
this.props.onChange();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide a 'worst' roll within the information we have
|
* Provide a 'worst' roll within the information we have
|
||||||
*/
|
*/
|
||||||
@@ -235,13 +276,13 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
* @return {React.Component} List
|
* @return {React.Component} List
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const language = this.context.language;
|
const { language, tooltip, termtip } = this.context;
|
||||||
const translate = language.translate;
|
const translate = language.translate;
|
||||||
const { tooltip, termtip } = this.context;
|
|
||||||
const { m } = this.props;
|
const { m } = this.props;
|
||||||
const { blueprintMenuOpened } = this.state;
|
const { blueprintMenuOpened, specialMenuOpened } = this.state;
|
||||||
|
|
||||||
const _toggleBlueprintsMenu = this._toggleBlueprintsMenu;
|
const _toggleBlueprintsMenu = this._toggleBlueprintsMenu;
|
||||||
|
const _toggleSpecialsMenu = this._toggleSpecialsMenu;
|
||||||
const _rollBest = this._rollBest;
|
const _rollBest = this._rollBest;
|
||||||
const _rollWorst = this._rollWorst;
|
const _rollWorst = this._rollWorst;
|
||||||
const _rollAverage = this._rollAverage;
|
const _rollAverage = this._rollAverage;
|
||||||
@@ -257,15 +298,31 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
blueprintLabel = translate('PHRASE_SELECT_BLUEPRINT');
|
blueprintLabel = translate('PHRASE_SELECT_BLUEPRINT');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let specialLabel;
|
||||||
|
let haveSpecial = false;
|
||||||
|
if (m.blueprint && m.blueprint.special) {
|
||||||
|
specialLabel = m.blueprint.special.name;
|
||||||
|
} else {
|
||||||
|
specialLabel = translate('PHRASE_SELECT_SPECIAL');
|
||||||
|
}
|
||||||
|
|
||||||
|
const showBlueprintsMenu = blueprintMenuOpened;
|
||||||
|
const showSpecial = haveBlueprint && this.state.specials.length > 0;
|
||||||
|
const showSpecialsMenu = specialMenuOpened;
|
||||||
|
const showRolls = haveBlueprint && !blueprintMenuOpened && !specialMenuOpened;
|
||||||
|
const showMods = !blueprintMenuOpened && !specialMenuOpened;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn('select', this.props.className)}
|
className={cn('select', this.props.className)}
|
||||||
onClick={(e) => e.stopPropagation() }
|
onClick={(e) => e.stopPropagation() }
|
||||||
onContextMenu={stopCtxPropagation}
|
onContextMenu={stopCtxPropagation}
|
||||||
>
|
>
|
||||||
<div className={ cn('section-menu', { selected: true })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
|
<div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
|
||||||
{ blueprintMenuOpened ? this.state.blueprints : '' }
|
{ showBlueprintsMenu ? this.state.blueprints : '' }
|
||||||
{ haveBlueprint ?
|
{ showSpecial ? <div className={ cn('section-menu', { selected: specialMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleSpecialsMenu}>{specialLabel}</div> : '' }
|
||||||
|
{ showSpecialsMenu ? this.state.specials : '' }
|
||||||
|
{ showRolls ?
|
||||||
<table style={{ width: '100%', backgroundColor: 'transparent' }}>
|
<table style={{ width: '100%', backgroundColor: 'transparent' }}>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -278,10 +335,10 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table> : '' }
|
</table> : '' }
|
||||||
{ blueprintMenuOpened ? '' :
|
{ showMods ?
|
||||||
<span onMouseOver={termtip.bind(null, 'HELP_MODIFICATIONS_MENU')} onMouseOut={tooltip.bind(null, null)} >
|
<span onMouseOver={termtip.bind(null, 'HELP_MODIFICATIONS_MENU')} onMouseOut={tooltip.bind(null, null)} >
|
||||||
{ this.state.modifications }
|
{ this.state.modifications }
|
||||||
</span> }
|
</span> : '' }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,11 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': !ship.canBoost() }) }>{translate('boost')}</th>
|
<th rowSpan={2} className={ cn({ 'bg-warning-disabled': !ship.canBoost() }) }>{translate('boost')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'damage per second')} onMouseLeave={hide} rowSpan={2}>{translate('DPS')}</th>
|
<th onMouseEnter={termtip.bind(null, 'damage per second')} onMouseLeave={hide} rowSpan={2}>{translate('DPS')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'energy per second')} onMouseLeave={hide} rowSpan={2}>{translate('EPS')}</th>
|
<th onMouseEnter={termtip.bind(null, 'energy per second')} onMouseLeave={hide} rowSpan={2}>{translate('EPS')}</th>
|
||||||
|
<th onMouseEnter={termtip.bind(null, 'time to drain WEP capacitor')} onMouseLeave={hide} rowSpan={2}>{translate('TTD')}</th>
|
||||||
<th onMouseEnter={termtip.bind(null, 'heat per second')} onMouseLeave={hide} rowSpan={2}>{translate('HPS')}</th>
|
<th onMouseEnter={termtip.bind(null, 'heat per second')} onMouseLeave={hide} rowSpan={2}>{translate('HPS')}</th>
|
||||||
<th rowSpan={2}>{translate('hardness')}</th>
|
<th onMouseEnter={termtip.bind(null, 'hull hardness')} onMouseLeave={hide} rowSpan={2}>{translate('hrd')}</th>
|
||||||
<th rowSpan={2}>{translate('armour')}</th>
|
<th onMouseEnter={termtip.bind(null, 'armour')} onMouseLeave={hide} rowSpan={2}>{translate('arm')}</th>
|
||||||
<th rowSpan={2}>{translate('shields')}</th>
|
<th onMouseEnter={termtip.bind(null, 'shields')} onMouseLeave={hide} rowSpan={2}>{translate('shld')}</th>
|
||||||
<th colSpan={3}>{translate('mass')}</th>
|
<th colSpan={3}>{translate('mass')}</th>
|
||||||
<th rowSpan={2}>{translate('cargo')}</th>
|
<th rowSpan={2}>{translate('cargo')}</th>
|
||||||
<th rowSpan={2}>{translate('fuel')}</th>
|
<th rowSpan={2}>{translate('fuel')}</th>
|
||||||
@@ -71,6 +72,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
|||||||
<td>{ ship.canBoost() ? <span>{int(ship.topBoost)} {u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td>
|
<td>{ ship.canBoost() ? <span>{int(ship.topBoost)} {u['m/s']}</span> : <span className='warning'>0 <Warning/></span> }</td>
|
||||||
<td>{f1(ship.totalDps)}</td>
|
<td>{f1(ship.totalDps)}</td>
|
||||||
<td>{f1(ship.totalEps)}</td>
|
<td>{f1(ship.totalEps)}</td>
|
||||||
|
<td>{ship.timeToDrain === Infinity ? '∞' : time(ship.timeToDrain)}</td>
|
||||||
<td>{f1(ship.totalHps)}</td>
|
<td>{f1(ship.totalHps)}</td>
|
||||||
<td>{int(ship.hardness)}</td>
|
<td>{int(ship.hardness)}</td>
|
||||||
<td>{int(ship.armour)}</td>
|
<td>{int(ship.armour)}</td>
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
||||||
<div/>
|
<div/>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
{ m.getOptimalMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptimalMass())}{units.T}</div> : null }
|
{ m.getMinMass() ? <div className='l'>{translate('minimum mass')}: {formats.int(m.getMinMass())}{units.T}</div> : null }
|
||||||
|
{ m.getOptMass() ? <div className='l'>{translate('optimal mass')}: {formats.int(m.getOptMass())}{units.T}</div> : null }
|
||||||
{ m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null }
|
{ m.getMaxMass() ? <div className='l'>{translate('max mass')}: {formats.int(m.getMaxMass())}{units.T}</div> : null }
|
||||||
{ m.getRange() ? <div className='l'>{translate('range')}: {formats.f2(m.getRange())}{units.km}</div> : null }
|
{ m.getRange() ? <div className='l'>{translate('range')}: {formats.f2(m.getRange())}{units.km}</div> : null }
|
||||||
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }
|
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ export const terms = {
|
|||||||
PHRASE_BLUEPRINT_RANDOM: 'Random selection between worst and best primary values for this blueprint',
|
PHRASE_BLUEPRINT_RANDOM: 'Random selection between worst and best primary values for this blueprint',
|
||||||
PHRASE_BLUEPRINT_BEST: 'Best primary values for this blueprint',
|
PHRASE_BLUEPRINT_BEST: 'Best primary values for this blueprint',
|
||||||
PHRASE_BLUEPRINT_RESET: 'Remove all modifications and blueprint',
|
PHRASE_BLUEPRINT_RESET: 'Remove all modifications and blueprint',
|
||||||
|
PHRASE_SELECT_SPECIAL: 'Click to select an experimental effect',
|
||||||
|
PHRASE_NO_SPECIAL: 'No experimental effect',
|
||||||
|
|
||||||
HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes',
|
HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes',
|
||||||
|
|
||||||
@@ -213,6 +215,8 @@ Along the top of the screen are some of the key values for your build. This is
|
|||||||
|
|
||||||
Here, along with most places in Coriolis, acronyms will have tooltips explaining what they mean. Hover over the acronym to obtain more detail, or look in the glossary at the end of this help.</p>
|
Here, along with most places in Coriolis, acronyms will have tooltips explaining what they mean. Hover over the acronym to obtain more detail, or look in the glossary at the end of this help.</p>
|
||||||
|
|
||||||
|
All values are the highest possible, assuming that you have maximum pips in the relevant capacitor (ENG for speed, WEP for time to drain, etc.).</p>
|
||||||
|
|
||||||
<h2>Modules</h2>
|
<h2>Modules</h2>
|
||||||
The next set of panels laid out horizontally across the screen contain the modules you have put in your build. From left to right these are the core modules, the internal modules, the hardpoints and the utility mounts. These represent the available slots in your ship and cannot be altered. Each slot has a class, or size, and in general any module up to a given size can fit in a given slot (exceptions being bulkheads, life support and sensors in core modules and restricted internal slots, which can only take a subset of module depending on their restrictions). </p>
|
The next set of panels laid out horizontally across the screen contain the modules you have put in your build. From left to right these are the core modules, the internal modules, the hardpoints and the utility mounts. These represent the available slots in your ship and cannot be altered. Each slot has a class, or size, and in general any module up to a given size can fit in a given slot (exceptions being bulkheads, life support and sensors in core modules and restricted internal slots, which can only take a subset of module depending on their restrictions). </p>
|
||||||
|
|
||||||
@@ -289,7 +293,7 @@ The damage received panel provides information about the effectiveness of your b
|
|||||||
<dt>Ctrl-e</dt><dd>open export dialogue (outfitting page only)</dd>
|
<dt>Ctrl-e</dt><dd>open export dialogue (outfitting page only)</dd>
|
||||||
<dt>Ctrl-h</dt><dd>open help dialogue</dd>
|
<dt>Ctrl-h</dt><dd>open help dialogue</dd>
|
||||||
<dt>Ctrl-i</dt><dd>open import dialogue</dd>
|
<dt>Ctrl-i</dt><dd>open import dialogue</dd>
|
||||||
<dt>Ctrl-l</dt><dd>open shortlink dialogue</dd>
|
<dt>Ctrl-o</dt><dd>open shortlink dialogue</dd>
|
||||||
<dt>Esc</dt><dd>close any open dialogue</dd>
|
<dt>Esc</dt><dd>close any open dialogue</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h1>Glossary</h1>
|
<h1>Glossary</h1>
|
||||||
|
|||||||
@@ -251,7 +251,6 @@ export default class ShipyardPage extends Page {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='page' style={{ fontSize: sizeRatio + 'em' }}>
|
<div className='page' style={{ fontSize: sizeRatio + 'em' }}>
|
||||||
<p style={{ textAlign: 'center' }}>This is <strong>Coriolis EDCD Edition</strong> - a temporary clone of <a href='https://coriolis.io/' target='_blank'>https://coriolis.io/</a> with added support for E:D 2.2. For more info see Settings / <Link href="/about" className='block'>About</Link></p>
|
|
||||||
<div style={{ whiteSpace: 'nowrap', margin: '0 auto', fontSize: '0.8em', position: 'relative', display: 'inline-block', maxWidth: '100%' }}>
|
<div style={{ whiteSpace: 'nowrap', margin: '0 auto', fontSize: '0.8em', position: 'relative', display: 'inline-block', maxWidth: '100%' }}>
|
||||||
<table style={{ width: '12em', position: 'absolute', zIndex: 1 }}>
|
<table style={{ width: '12em', position: 'absolute', zIndex: 1 }}>
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Module from './Module';
|
|||||||
*/
|
*/
|
||||||
export function jumpRange(mass, fsd, fuel) {
|
export function jumpRange(mass, fsd, fuel) {
|
||||||
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
|
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
|
||||||
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptimalMass() : fsd.optmass;
|
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
|
||||||
return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass;
|
return Math.pow(Math.min(fuel === undefined ? fsdMaxFuelPerJump : fuel, fsdMaxFuelPerJump) / fsd.fuelmul, 1 / fsd.fuelpower) * fsdOptimalMass / mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ export function jumpRange(mass, fsd, fuel) {
|
|||||||
*/
|
*/
|
||||||
export function fastestRange(mass, fsd, fuel) {
|
export function fastestRange(mass, fsd, fuel) {
|
||||||
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
|
let fsdMaxFuelPerJump = fsd instanceof Module ? fsd.getMaxFuelPerJump() : fsd.maxfuel;
|
||||||
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptimalMass() : fsd.optmass;
|
let fsdOptimalMass = fsd instanceof Module ? fsd.getOptMass() : fsd.optmass;
|
||||||
let fuelRemaining = fuel % fsdMaxFuelPerJump; // Fuel left after making N max jumps
|
let fuelRemaining = fuel % fsdMaxFuelPerJump; // Fuel left after making N max jumps
|
||||||
let jumps = Math.floor(fuel / fsdMaxFuelPerJump);
|
let jumps = Math.floor(fuel / fsdMaxFuelPerJump);
|
||||||
mass += fuelRemaining;
|
mass += fuelRemaining;
|
||||||
|
|||||||
@@ -37,48 +37,98 @@ export default class Module {
|
|||||||
/**
|
/**
|
||||||
* Get a value for a given modification
|
* Get a value for a given modification
|
||||||
* @param {Number} name The name of the modification
|
* @param {Number} name The name of the modification
|
||||||
|
* @param {Number} raw True if the value returned should be raw i.e. without the influence of special effects
|
||||||
* @return {object} The value of the modification. If it is a numeric value then it is returned as an integer value scaled so that 1.23% == 123
|
* @return {object} The value of the modification. If it is a numeric value then it is returned as an integer value scaled so that 1.23% == 123
|
||||||
*/
|
*/
|
||||||
getModValue(name) {
|
getModValue(name, raw) {
|
||||||
return this.mods && this.mods[name] ? this.mods[name] : null;
|
let result = this.mods && this.mods[name] ? this.mods[name] : null;
|
||||||
|
if ((!raw) && this.blueprint && this.blueprint.special) {
|
||||||
|
// This module has a special effect, see if we need to alter our returned value
|
||||||
|
const modifierActions = Modifications.modifierActions[this.blueprint.special.edname];
|
||||||
|
if (modifierActions && modifierActions[name]) {
|
||||||
|
// this special effect modifies our returned value
|
||||||
|
const modification = Modifications.modifications[name];
|
||||||
|
if (modification.method === 'additive') {
|
||||||
|
result = result + modifierActions[name];
|
||||||
|
} else if (modification.method === 'overwrite') {
|
||||||
|
result = modifierActions[name];
|
||||||
|
} else {
|
||||||
|
// rate of fire is special, as it's really burst interval. Handle that here
|
||||||
|
let mod = null;
|
||||||
|
if (name === 'rof') {
|
||||||
|
mod = 1 / (1 + modifierActions[name]) - 1;
|
||||||
|
} else {
|
||||||
|
mod = modifierActions[name];
|
||||||
|
}
|
||||||
|
result = (((1 + result / 10000) * (1 + mod)) - 1) * 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitise the resultant value to 4dp equivalent
|
||||||
|
return isNaN(result) ? result : Math.round(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a value for a given modification ID
|
* Set a value for a given modification ID
|
||||||
* @param {Number} name The name of the modification
|
* @param {Number} name The name of the modification
|
||||||
* @param {object} value The value of the modification. If it is a numeric value then it should be an integer scaled so that -2.34% == -234
|
* @param {object} value The value of the modification. If it is a numeric value then it should be an integer scaled so that -2.34% == -234
|
||||||
|
* @param {bool} valueiswithspecial true if the value includes the special effect (when coming from a UI component)
|
||||||
*/
|
*/
|
||||||
setModValue(name, value) {
|
setModValue(name, value, valueiswithspecial) {
|
||||||
if (!this.mods) {
|
if (!this.mods) {
|
||||||
this.mods = {};
|
this.mods = {};
|
||||||
}
|
}
|
||||||
|
if (valueiswithspecial && this.blueprint && this.blueprint.special) {
|
||||||
|
// This module has a special effect, see if we need to alter the stored value
|
||||||
|
const modifierActions = Modifications.modifierActions[this.blueprint.special.edname];
|
||||||
|
if (modifierActions && modifierActions[name]) {
|
||||||
|
// This special effect modifies the value being set, so we need to revert it prior to storing the value
|
||||||
|
const modification = Modifications.modifications[name];
|
||||||
|
if (modification.method === 'additive') {
|
||||||
|
value = value - modifierActions[name];
|
||||||
|
} else if (modification.method === 'overwrite') {
|
||||||
|
value = null;
|
||||||
|
} else {
|
||||||
|
// rate of fire is special, as it's really burst interval. Handle that here
|
||||||
|
let mod = null;
|
||||||
|
if (name === 'rof') {
|
||||||
|
mod = 1 / (1 + modifierActions[name]) - 1;
|
||||||
|
} else {
|
||||||
|
mod = modifierActions[name];
|
||||||
|
}
|
||||||
|
value = ((value / 10000 + 1) / (1 + mod) - 1) * 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (value == null || value == 0) {
|
if (value == null || value == 0) {
|
||||||
delete this.mods[name];
|
delete this.mods[name];
|
||||||
} else {
|
} else {
|
||||||
if (isNaN(value)) {
|
|
||||||
this.mods[name] = value;
|
this.mods[name] = value;
|
||||||
} else {
|
|
||||||
// Round just to be sure
|
|
||||||
this.mods[name] = Math.round(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to obtain a modified value using standard multipliers
|
* Helper to obtain a modified value using standard multipliers
|
||||||
* @param {String} name the name of the modifier to obtain
|
* @param {String} name the name of the modifier to obtain
|
||||||
* @param {Boolean} additive Optional true if the value is additive rather than multiplicative
|
|
||||||
* @return {Number} the mass of this module
|
* @return {Number} the mass of this module
|
||||||
*/
|
*/
|
||||||
_getModifiedValue(name, additive) {
|
_getModifiedValue(name) {
|
||||||
let result = this[name] || (additive ? 0 : null); // Additive NULL === 0
|
|
||||||
if (result != null) {
|
|
||||||
const modification = Modifications.modifications[name];
|
const modification = Modifications.modifications[name];
|
||||||
if (!modification) {
|
let result = this[name];
|
||||||
return result;
|
|
||||||
|
if (!result) {
|
||||||
|
if (modification && modification.method === 'additive') {
|
||||||
|
// Additive modifications start at 0 rather than NULL
|
||||||
|
result = 0;
|
||||||
|
} else {
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
if (modification) {
|
||||||
// We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise
|
// We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise
|
||||||
// we divide by 100. Both ways we end up with a value with two decimal places
|
// we divide by 100. Both ways we end up with a value with two decimal places
|
||||||
let modValue;
|
let modValue;
|
||||||
@@ -90,21 +140,22 @@ export default class Module {
|
|||||||
modValue = this.getModValue(name);
|
modValue = this.getModValue(name);
|
||||||
}
|
}
|
||||||
if (modValue) {
|
if (modValue) {
|
||||||
if (additive) {
|
if (modification.method === 'additive') {
|
||||||
result = result + modValue;
|
result = result + modValue;
|
||||||
|
} else if (modification.method === 'overwrite') {
|
||||||
|
result = modValue;
|
||||||
} else {
|
} else {
|
||||||
result = result * (1 + modValue);
|
result = result * (1 + modValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (name === 'burst') {
|
if (name === 'burst') {
|
||||||
// Burst is special, as if it can not exist but have a modification
|
// Burst is special, as if it can not exist but have a modification
|
||||||
const modValue = this.getModValue(name) / 100;
|
result = this.getModValue(name) / 100;
|
||||||
return modValue;
|
|
||||||
} else if (name === 'burstrof') {
|
} else if (name === 'burstrof') {
|
||||||
// Burst rate of fire is special, as if it can not exist but have a modification
|
// Burst rate of fire is special, as if it can not exist but have a modification
|
||||||
const modValue = this.getModValue(name) / 100;
|
result = this.getModValue(name) / 100;
|
||||||
return modValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,30 +210,6 @@ export default class Module {
|
|||||||
return this._getModifiedValue('eff');
|
return this._getModifiedValue('eff');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the maximum mass of this module, taking in to account modifications
|
|
||||||
* @return {Number} the maximum mass of this module
|
|
||||||
*/
|
|
||||||
getMaxMass() {
|
|
||||||
return this._getModifiedValue('maxmass');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the optimal mass of this module, taking in to account modifications
|
|
||||||
* @return {Number} the optimal mass of this module
|
|
||||||
*/
|
|
||||||
getOptimalMass() {
|
|
||||||
return this._getModifiedValue('optmass');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the optimal multiplier of this module, taking in to account modifications
|
|
||||||
* @return {Number} the optimal multiplier of this module
|
|
||||||
*/
|
|
||||||
getOptimalMultiplier() {
|
|
||||||
return this._getModifiedValue('optmult');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the maximum fuel per jump for this module, taking in to account modifications
|
* Get the maximum fuel per jump for this module, taking in to account modifications
|
||||||
* @return {Number} the maximum fuel per jump of this module
|
* @return {Number} the maximum fuel per jump of this module
|
||||||
@@ -244,7 +271,7 @@ export default class Module {
|
|||||||
* @return {Number} the kinetic resistance of this module
|
* @return {Number} the kinetic resistance of this module
|
||||||
*/
|
*/
|
||||||
getKineticResistance() {
|
getKineticResistance() {
|
||||||
return this._getModifiedValue('kinres', true);
|
return this._getModifiedValue('kinres');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,7 +279,7 @@ export default class Module {
|
|||||||
* @return {Number} the thermal resistance of this module
|
* @return {Number} the thermal resistance of this module
|
||||||
*/
|
*/
|
||||||
getThermalResistance() {
|
getThermalResistance() {
|
||||||
return this._getModifiedValue('thermres', true);
|
return this._getModifiedValue('thermres');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,7 +287,7 @@ export default class Module {
|
|||||||
* @return {Number} the explosive resistance of this module
|
* @return {Number} the explosive resistance of this module
|
||||||
*/
|
*/
|
||||||
getExplosiveResistance() {
|
getExplosiveResistance() {
|
||||||
return this._getModifiedValue('explres', true);
|
return this._getModifiedValue('explres');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -671,9 +698,25 @@ export default class Module {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shot speed for this module, taking in to account modifications
|
* Get the shot speed for this module, taking in to account modifications
|
||||||
* @return {string} the damage distribution for this module
|
* @return {string} the shot speed for this module
|
||||||
*/
|
*/
|
||||||
getShotSpeed() {
|
getShotSpeed() {
|
||||||
return this._getModifiedValue('shotspeed');
|
return this._getModifiedValue('shotspeed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the spinup for this module, taking in to account modifications
|
||||||
|
* @return {string} the spinup for this module
|
||||||
|
*/
|
||||||
|
getSpinup() {
|
||||||
|
return this._getModifiedValue('spinup');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time for this module, taking in to account modifications
|
||||||
|
* @return {string} the time for this module
|
||||||
|
*/
|
||||||
|
getTime() {
|
||||||
|
return this._getModifiedValue('time');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export function toDetailedBuild(buildName, ship) {
|
|||||||
code = ship.toString();
|
code = ship.toString();
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
$schema: 'http://cdn.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: [{
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ export default class Ship {
|
|||||||
m.mods = {};
|
m.mods = {};
|
||||||
this.updatePowerGenerated()
|
this.updatePowerGenerated()
|
||||||
.updatePowerUsed()
|
.updatePowerUsed()
|
||||||
|
.recalculateMass()
|
||||||
.updateJumpStats()
|
.updateJumpStats()
|
||||||
.recalculateShield()
|
.recalculateShield()
|
||||||
.recalculateShieldCells()
|
.recalculateShieldCells()
|
||||||
@@ -426,6 +427,7 @@ export default class Ship {
|
|||||||
.recalculateDps()
|
.recalculateDps()
|
||||||
.recalculateEps()
|
.recalculateEps()
|
||||||
.recalculateHps()
|
.recalculateHps()
|
||||||
|
.recalculateTtd()
|
||||||
.updateMovement();
|
.updateMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,12 +440,13 @@ export default class Ship {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a modification value
|
* Set a modification value and update ship stats
|
||||||
* @param {Object} m The module to change
|
* @param {Object} m The module to change
|
||||||
* @param {Object} name The name of the modification to change
|
* @param {Object} name The name of the modification to change
|
||||||
* @param {Number} value The new value of the modification. The value of the modification is scaled to provide two decimal places of precision in an integer. For example 1.23% is stored as 123
|
* @param {Number} value The new value of the modification. The value of the modification is scaled to provide two decimal places of precision in an integer. For example 1.23% is stored as 123
|
||||||
|
* @param {bool} sentfromui True if this update was sent from the UI
|
||||||
*/
|
*/
|
||||||
setModification(m, name, value) {
|
setModification(m, name, value, sentfromui) {
|
||||||
if (isNaN(value)) {
|
if (isNaN(value)) {
|
||||||
// Value passed is invalid; reset it to 0
|
// Value passed is invalid; reset it to 0
|
||||||
value = 0;
|
value = 0;
|
||||||
@@ -452,58 +455,59 @@ export default class Ship {
|
|||||||
// Handle special cases
|
// Handle special cases
|
||||||
if (name === 'pgen') {
|
if (name === 'pgen') {
|
||||||
// Power generation
|
// Power generation
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.updatePowerGenerated();
|
this.updatePowerGenerated();
|
||||||
} else if (name === 'power') {
|
} else if (name === 'power') {
|
||||||
// Power usage
|
// Power usage
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.updatePowerUsed();
|
this.updatePowerUsed();
|
||||||
} else if (name === 'mass') {
|
} else if (name === 'mass') {
|
||||||
// Mass
|
// Mass
|
||||||
let oldMass = m.getMass();
|
m.setModValue(name, value, sentfromui);
|
||||||
m.setModValue(name, value);
|
this.recalculateMass();
|
||||||
let newMass = m.getMass();
|
|
||||||
this.unladenMass = this.unladenMass - oldMass + newMass;
|
|
||||||
this.ladenMass = this.ladenMass - oldMass + newMass;
|
|
||||||
this.updateMovement();
|
this.updateMovement();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
} else if (name === 'maxfuel') {
|
} else if (name === 'maxfuel') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
} else if (name === 'optmass') {
|
} else if (name === 'optmass') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
// Could be for any of thrusters, FSD or shield
|
// Could be for any of thrusters, FSD or shield
|
||||||
this.updateMovement();
|
this.updateMovement();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
this.recalculateShield();
|
this.recalculateShield();
|
||||||
} else if (name === 'optmul') {
|
} else if (name === 'optmul') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
// Could be for any of thrusters, FSD or shield
|
// Could be for any of thrusters, FSD or shield
|
||||||
this.updateMovement();
|
this.updateMovement();
|
||||||
this.updateJumpStats();
|
this.updateJumpStats();
|
||||||
this.recalculateShield();
|
this.recalculateShield();
|
||||||
} else if (name === 'shieldboost') {
|
} else if (name === 'shieldboost') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.recalculateShield();
|
this.recalculateShield();
|
||||||
} else if (name === 'hullboost' || name === 'hullreinforcement' || name === 'modulereinforcement') {
|
} else if (name === 'hullboost' || name === 'hullreinforcement' || name === 'modulereinforcement') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.recalculateArmour();
|
this.recalculateArmour();
|
||||||
} else if (name === 'shieldreinforcement') {
|
} else if (name === 'shieldreinforcement') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.recalculateShieldCells();
|
this.recalculateShieldCells();
|
||||||
} else if (name === 'burst' || name == 'burstrof' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') {
|
} else if (name === 'burst' || name == 'burstrof' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
this.recalculateDps();
|
this.recalculateDps();
|
||||||
this.recalculateHps();
|
this.recalculateHps();
|
||||||
this.recalculateEps();
|
this.recalculateEps();
|
||||||
|
this.recalculateTtd();
|
||||||
} else if (name === 'explres' || name === 'kinres' || name === 'thermres') {
|
} else if (name === 'explres' || name === 'kinres' || name === 'thermres') {
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
// Could be for shields or armour
|
// Could be for shields or armour
|
||||||
this.recalculateArmour();
|
this.recalculateArmour();
|
||||||
this.recalculateShield();
|
this.recalculateShield();
|
||||||
|
} else if (name === 'wepcap' || name === 'weprate') {
|
||||||
|
m.setModValue(name, value, sentfromui);
|
||||||
|
this.recalculateTtd();
|
||||||
} else {
|
} else {
|
||||||
// Generic
|
// Generic
|
||||||
m.setModValue(name, value);
|
m.setModValue(name, value, sentfromui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,6 +630,7 @@ export default class Ship {
|
|||||||
if (comps) {
|
if (comps) {
|
||||||
this.updatePowerGenerated()
|
this.updatePowerGenerated()
|
||||||
.updatePowerUsed()
|
.updatePowerUsed()
|
||||||
|
.recalculateMass()
|
||||||
.updateJumpStats()
|
.updateJumpStats()
|
||||||
.recalculateShield()
|
.recalculateShield()
|
||||||
.recalculateShieldCells()
|
.recalculateShieldCells()
|
||||||
@@ -633,6 +638,7 @@ export default class Ship {
|
|||||||
.recalculateDps()
|
.recalculateDps()
|
||||||
.recalculateEps()
|
.recalculateEps()
|
||||||
.recalculateHps()
|
.recalculateHps()
|
||||||
|
.recalculateTtd()
|
||||||
.updateMovement();
|
.updateMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,6 +820,7 @@ export default class Ship {
|
|||||||
|
|
||||||
if (slot.m.getEps()) {
|
if (slot.m.getEps()) {
|
||||||
this.recalculateEps();
|
this.recalculateEps();
|
||||||
|
this.recalculateTtd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -850,6 +857,7 @@ export default class Ship {
|
|||||||
*/
|
*/
|
||||||
updateStats(slot, n, old, preventUpdate) {
|
updateStats(slot, n, old, preventUpdate) {
|
||||||
let powerGeneratedChange = slot == this.standard[0];
|
let powerGeneratedChange = slot == this.standard[0];
|
||||||
|
let powerDistributorChange = slot == this.standard[4];
|
||||||
let powerUsedChange = false;
|
let powerUsedChange = false;
|
||||||
let dpsChanged = n && n.getDps() || old && old.getDps();
|
let dpsChanged = n && n.getDps() || old && old.getDps();
|
||||||
let epsChanged = n && n.getEps() || old && old.getEps();
|
let epsChanged = n && n.getEps() || old && old.getEps();
|
||||||
@@ -862,15 +870,6 @@ export default class Ship {
|
|||||||
let shieldCellsChange = (n && n.grp === 'scb') || (old && old.grp === 'scb');
|
let shieldCellsChange = (n && n.grp === 'scb') || (old && old.grp === 'scb');
|
||||||
|
|
||||||
if (old) { // Old modul now being removed
|
if (old) { // Old modul now being removed
|
||||||
switch (old.grp) {
|
|
||||||
case 'ft':
|
|
||||||
this.fuelCapacity -= old.fuel;
|
|
||||||
break;
|
|
||||||
case 'cr':
|
|
||||||
this.cargoCapacity -= old.cargo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot.incCost && old.cost) {
|
if (slot.incCost && old.cost) {
|
||||||
this.totalCost -= old.cost * this.moduleCostMultiplier;
|
this.totalCost -= old.cost * this.moduleCostMultiplier;
|
||||||
}
|
}
|
||||||
@@ -878,20 +877,9 @@ export default class Ship {
|
|||||||
if (old.getPowerUsage() > 0 && slot.enabled) {
|
if (old.getPowerUsage() > 0 && slot.enabled) {
|
||||||
powerUsedChange = true;
|
powerUsedChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.unladenMass -= old.getMass() || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n) {
|
if (n) {
|
||||||
switch (n.grp) {
|
|
||||||
case 'ft':
|
|
||||||
this.fuelCapacity += n.fuel;
|
|
||||||
break;
|
|
||||||
case 'cr':
|
|
||||||
this.cargoCapacity += n.cargo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot.incCost && n.cost) {
|
if (slot.incCost && n.cost) {
|
||||||
this.totalCost += n.cost * this.moduleCostMultiplier;
|
this.totalCost += n.cost * this.moduleCostMultiplier;
|
||||||
}
|
}
|
||||||
@@ -899,13 +887,11 @@ export default class Ship {
|
|||||||
if (n.power && slot.enabled) {
|
if (n.power && slot.enabled) {
|
||||||
powerUsedChange = true;
|
powerUsedChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.unladenMass += n.getMass() || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ladenMass = this.unladenMass + this.cargoCapacity + this.fuelCapacity;
|
|
||||||
|
|
||||||
if (!preventUpdate) {
|
if (!preventUpdate) {
|
||||||
|
// Must recalculate mass first, as movement, jump etc. relies on it
|
||||||
|
this.recalculateMass();
|
||||||
if (dpsChanged) {
|
if (dpsChanged) {
|
||||||
this.recalculateDps();
|
this.recalculateDps();
|
||||||
}
|
}
|
||||||
@@ -918,6 +904,9 @@ export default class Ship {
|
|||||||
if (powerGeneratedChange) {
|
if (powerGeneratedChange) {
|
||||||
this.updatePowerGenerated();
|
this.updatePowerGenerated();
|
||||||
}
|
}
|
||||||
|
if (powerDistributorChange) {
|
||||||
|
this.recalculateTtd();
|
||||||
|
}
|
||||||
if (powerUsedChange) {
|
if (powerUsedChange) {
|
||||||
this.updatePowerUsed();
|
this.updatePowerUsed();
|
||||||
}
|
}
|
||||||
@@ -956,7 +945,34 @@ export default class Ship {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate damage per second for weapons
|
* Calculate time to drain WEP capacitor
|
||||||
|
* @return {this} The ship instance (for chaining operations)
|
||||||
|
*/
|
||||||
|
recalculateTtd() {
|
||||||
|
let totalSEps = 0;
|
||||||
|
|
||||||
|
for (let slotNum in this.hardpoints) {
|
||||||
|
const slot = this.hardpoints[slotNum];
|
||||||
|
if (slot.m && slot.enabled && slot.type === 'WEP' && slot.m.getDps()) {
|
||||||
|
totalSEps += slot.m.getClip() ? (slot.m.getClip() * slot.m.getEps() / slot.m.getRoF()) / ((slot.m.getClip() / slot.m.getRoF()) + slot.m.getReload()) : slot.m.getEps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the drain time
|
||||||
|
const drainPerSecond = totalSEps - this.standard[4].m.getWeaponsRechargeRate();
|
||||||
|
if (drainPerSecond <= 0) {
|
||||||
|
// Can fire forever
|
||||||
|
this.timeToDrain = Infinity;
|
||||||
|
} else {
|
||||||
|
const initialCharge = this.standard[4].m.getWeaponsCapacity();
|
||||||
|
this.timeToDrain = initialCharge / drainPerSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate damage per second and related items for weapons
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
*/
|
*/
|
||||||
recalculateDps() {
|
recalculateDps() {
|
||||||
@@ -978,7 +994,7 @@ export default class Ship {
|
|||||||
|
|
||||||
for (let slotNum in this.hardpoints) {
|
for (let slotNum in this.hardpoints) {
|
||||||
const slot = this.hardpoints[slotNum];
|
const slot = this.hardpoints[slotNum];
|
||||||
if (slot.m && slot.enabled && slot.m.getDps()) {
|
if (slot.m && slot.enabled && slot.type === 'WEP' && slot.m.getDps()) {
|
||||||
const dpe = slot.m.getEps() === 0 ? 0 : slot.m.getDps() / slot.m.getEps();
|
const dpe = slot.m.getEps() === 0 ? 0 : slot.m.getDps() / slot.m.getEps();
|
||||||
const dps = slot.m.getDps();
|
const dps = slot.m.getDps();
|
||||||
const sdps = slot.m.getClip() ? (slot.m.getClip() * slot.m.getDps() / slot.m.getRoF()) / ((slot.m.getClip() / slot.m.getRoF()) + slot.m.getReload()) : dps;
|
const sdps = slot.m.getClip() ? (slot.m.getClip() * slot.m.getDps() / slot.m.getRoF()) / ((slot.m.getClip() / slot.m.getRoF()) + slot.m.getReload()) : dps;
|
||||||
@@ -1039,7 +1055,7 @@ export default class Ship {
|
|||||||
|
|
||||||
for (let slotNum in this.hardpoints) {
|
for (let slotNum in this.hardpoints) {
|
||||||
const slot = this.hardpoints[slotNum];
|
const slot = this.hardpoints[slotNum];
|
||||||
if (slot.m && slot.enabled && slot.m.getHps()) {
|
if (slot.m && slot.enabled && slot.type === 'WEP' && slot.m.getHps()) {
|
||||||
totalHps += slot.m.getHps();
|
totalHps += slot.m.getHps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1057,7 +1073,7 @@ export default class Ship {
|
|||||||
|
|
||||||
for (let slotNum in this.hardpoints) {
|
for (let slotNum in this.hardpoints) {
|
||||||
const slot = this.hardpoints[slotNum];
|
const slot = this.hardpoints[slotNum];
|
||||||
if (slot.m && slot.enabled && slot.m.getEps()) {
|
if (slot.m && slot.enabled && slot.m.getEps() && slot.type === 'WEP') {
|
||||||
totalEps += slot.m.getEps();
|
totalEps += slot.m.getEps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1129,6 +1145,55 @@ export default class Ship {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eecalculate mass
|
||||||
|
* @return {this} The ship instance (for chaining operations)
|
||||||
|
*/
|
||||||
|
recalculateMass() {
|
||||||
|
let unladenMass = this.hullMass;
|
||||||
|
let cargoCapacity = 0;
|
||||||
|
let fuelCapacity = 0;
|
||||||
|
|
||||||
|
unladenMass += this.bulkheads.m.getMass();
|
||||||
|
|
||||||
|
for (let slotNum in this.standard) {
|
||||||
|
const slot = this.standard[slotNum];
|
||||||
|
if (slot.m) {
|
||||||
|
unladenMass += slot.m.getMass();
|
||||||
|
if (slot.m.grp === 'ft') {
|
||||||
|
fuelCapacity += slot.m.fuel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let slotNum in this.internal) {
|
||||||
|
const slot = this.internal[slotNum];
|
||||||
|
if (slot.m) {
|
||||||
|
unladenMass += slot.m.getMass();
|
||||||
|
if (slot.m.grp === 'ft') {
|
||||||
|
fuelCapacity += slot.m.fuel;
|
||||||
|
} else if (slot.m.grp === 'cr') {
|
||||||
|
cargoCapacity += slot.m.cargo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let slotNum in this.hardpoints) {
|
||||||
|
const slot = this.hardpoints[slotNum];
|
||||||
|
if (slot.m) {
|
||||||
|
unladenMass += slot.m.getMass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update global stats
|
||||||
|
this.unladenMass = unladenMass;
|
||||||
|
this.cargoCapacity = cargoCapacity;
|
||||||
|
this.fuelCapacity = fuelCapacity;
|
||||||
|
this.ladenMass = unladenMass + fuelCapacity + cargoCapacity;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update movement values
|
* Update movement values
|
||||||
* @return {this} The ship instance (for chaining operations)
|
* @return {this} The ship instance (for chaining operations)
|
||||||
@@ -1376,7 +1441,7 @@ export default class Ship {
|
|||||||
for (let modKey in this.bulkheads.m.mods) {
|
for (let modKey in this.bulkheads.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.modules['bh'] && Modifications.modules['bh'].modifications.indexOf(modKey) != -1) {
|
if (Modifications.modules['bh'] && Modifications.modules['bh'].modifications.indexOf(modKey) != -1) {
|
||||||
bulkheadMods.push({ id: Modifications.modifications[modKey].id, value: this.bulkheads.m.getModValue(modKey) });
|
bulkheadMods.push({ id: Modifications.modifications[modKey].id, value: this.bulkheads.m.getModValue(modKey, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bulkheadBlueprint = this.bulkheads.m.blueprint;
|
bulkheadBlueprint = this.bulkheads.m.blueprint;
|
||||||
@@ -1391,7 +1456,7 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1406,7 +1471,7 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1421,7 +1486,7 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
if (Modifications.modules[slot.m.grp] && Modifications.modules[slot.m.grp].modifications.indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,6 +308,9 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
|||||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_falloffrange_from_range') {
|
} else if (modifiers.modifiers[i].name === 'mod_weapon_falloffrange_from_range') {
|
||||||
// Obtain the falloff value directly from the range
|
// Obtain the falloff value directly from the range
|
||||||
module.setModValue('fallofffromrange', 1);
|
module.setModValue('fallofffromrange', 1);
|
||||||
|
} else if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) {
|
||||||
|
// We don't add special effects directly, but keep a note of them so they can be added when fetching values
|
||||||
|
special = Modifications.specials[modifiers.modifiers[i].name];
|
||||||
} else {
|
} else {
|
||||||
// Look up the modifiers to find what we need to do
|
// Look up the modifiers to find what we need to do
|
||||||
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
||||||
@@ -327,11 +330,6 @@ function _addModifications(module, modifiers, blueprint, grade) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note the special if present
|
|
||||||
if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) {
|
|
||||||
special = Modifications.specials[modifiers.modifiers[i].name];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the blueprint ID, grade and special
|
// Add the blueprint ID, grade and special
|
||||||
|
|||||||
@@ -151,13 +151,15 @@ export function diffDetails(language, m, mm) {
|
|||||||
let mmMass = mm ? mm.getMass() : 0;
|
let mmMass = mm ? mm.getMass() : 0;
|
||||||
if (mMass != mmMass) propDiffs.push(<div key='mass'>{translate('mass')}: <span className={diffClass(mMass, mmMass, true)}>{diff(formats.round, mMass, mmMass)}{units.T}</span></div>);
|
if (mMass != mmMass) propDiffs.push(<div key='mass'>{translate('mass')}: <span className={diffClass(mMass, mmMass, true)}>{diff(formats.round, mMass, mmMass)}{units.T}</span></div>);
|
||||||
|
|
||||||
|
if (m.grp === 'pp') {
|
||||||
let mPowerGeneration = m.pgen || 0;
|
let mPowerGeneration = m.pgen || 0;
|
||||||
let mmPowerGeneration = mm ? mm.getPowerGeneration() : 0;
|
let mmPowerGeneration = mm ? mm.getPowerGeneration() : 0;
|
||||||
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MJ}</span></div>);
|
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MJ}</span></div>);
|
||||||
|
} else {
|
||||||
let mPowerUsage = m.power || 0;
|
let mPowerUsage = m.power || 0;
|
||||||
let mmPowerUsage = mm ? mm.getPowerUsage() : 0;
|
let mmPowerUsage = mm ? mm.getPowerUsage() : 0;
|
||||||
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MJ}</span></div>);
|
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MJ}</span></div>);
|
||||||
|
}
|
||||||
|
|
||||||
let mDps = m.damage * (m.rpshot || 1) * (m.rof || 1) || 0;
|
let mDps = m.damage * (m.rpshot || 1) * (m.rof || 1) || 0;
|
||||||
let mmDps = mm ? mm.getDps() || 0 : 0;
|
let mmDps = mm ? mm.getDps() || 0 : 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "Coriolis.io",
|
"name": "Coriolis EDCD Edition",
|
||||||
"short_name": "Coriolis",
|
"short_name": "Coriolis",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"density": "4.0"
|
"density": "4.0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"start_url": "http:\/\/coriolis.io",
|
"start_url": "https:\/\/edcd.coriolis.io",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"orientation": "portrait"
|
"orientation": "portrait"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||||
"id": "http://cdn.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": "http://cdn.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": "http://cdn.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": "http://cdn.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",
|
||||||
|
|||||||
Reference in New Issue
Block a user