@elite-dangerous-almanac/core 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROVENANCE/astro/SOURCES.md +13 -12
- package/PROVENANCE/commodities/SOURCES.md +50 -6
- package/PROVENANCE/equipment/SOURCES.md +98 -20
- package/PROVENANCE/i18n/SOURCES.md +186 -80
- package/PROVENANCE/ships/SOURCES.md +344 -200
- package/README.md +10 -2
- package/THIRD_PARTY_NOTICES.md +11 -3
- package/dist/astro/body-rings.d.ts +2 -2
- package/dist/astro/codex-region-lookup.d.ts +1 -1
- package/dist/astro/codex-region-lookup.js +1 -1
- package/dist/astro/hand-authored-regions.d.ts +1 -1
- package/dist/astro/index.d.ts +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/astro/naming-region-origins.d.ts +1 -1
- package/dist/astro/naming-region-origins.js +1 -1
- package/dist/astro/nebulae-all.d.ts +4 -6
- package/dist/astro/nebulae-all.js +1 -1
- package/dist/astro/nebulae-all.js.map +1 -1
- package/dist/astro/nebulae-planetary.d.ts +4 -5
- package/dist/astro/nebulae-planetary.js +1 -1
- package/dist/astro/nebulae-procgen.d.ts +3 -3
- package/dist/astro/nebulae-real.d.ts +3 -3
- package/dist/astro/nebulae.d.ts +8 -8
- package/dist/astro/permit-locked-regions.d.ts +2 -2
- package/dist/astro/permit-locked-systems.d.ts +1 -1
- package/dist/astro/permit-locks.d.ts +2 -2
- package/dist/astro/procedural-system.d.ts +3 -3
- package/dist/astro/procedural-system.js +1 -1
- package/dist/astro/system-address.d.ts +1 -1
- package/dist/astro/system-address.js +1 -1
- package/dist/astro/system-name.js +1 -1
- package/dist/{chunk-XSLPWM5N.js → chunk-2J6NNI3Y.js} +1 -1
- package/dist/{chunk-DWRNXUAX.js → chunk-2KIZN3BY.js} +1 -1
- package/dist/{chunk-J7BM5NGK.js → chunk-2TY42PTF.js} +1 -1
- package/dist/{chunk-773VO2GK.js → chunk-4T3TTYUT.js} +1 -1
- package/dist/{chunk-773VO2GK.js.map → chunk-4T3TTYUT.js.map} +1 -1
- package/dist/{chunk-W5ULI75F.js → chunk-7C7NJWCF.js} +1 -1
- package/dist/{chunk-W5ULI75F.js.map → chunk-7C7NJWCF.js.map} +1 -1
- package/dist/{chunk-IMNOEFUE.js → chunk-7Y5EK2VO.js} +1 -1
- package/dist/{chunk-IMNOEFUE.js.map → chunk-7Y5EK2VO.js.map} +1 -1
- package/dist/{chunk-2OBUSQA7.js → chunk-AAU7OM47.js} +1 -1
- package/dist/{chunk-2OBUSQA7.js.map → chunk-AAU7OM47.js.map} +1 -1
- package/dist/{chunk-GIGRBFIJ.js → chunk-AC3U7LRK.js} +1 -1
- package/dist/{chunk-GIGRBFIJ.js.map → chunk-AC3U7LRK.js.map} +1 -1
- package/dist/{chunk-BJU27V6C.js → chunk-AUBV6S7V.js} +1 -1
- package/dist/{chunk-BJU27V6C.js.map → chunk-AUBV6S7V.js.map} +1 -1
- package/dist/{chunk-DI5RXSJR.js → chunk-BVLBS2QY.js} +1 -1
- package/dist/{chunk-DI5RXSJR.js.map → chunk-BVLBS2QY.js.map} +1 -1
- package/dist/{chunk-IN36YSS4.js → chunk-C3YZ5KTA.js} +1 -1
- package/dist/{chunk-IN36YSS4.js.map → chunk-C3YZ5KTA.js.map} +1 -1
- package/dist/{chunk-6UNAD74Z.js → chunk-C4FUV6GF.js} +1 -1
- package/dist/{chunk-6UNAD74Z.js.map → chunk-C4FUV6GF.js.map} +1 -1
- package/dist/chunk-CEF7SMB2.js +1 -0
- package/dist/chunk-CEF7SMB2.js.map +1 -0
- package/dist/chunk-E2HDF6PJ.js +1 -0
- package/dist/chunk-E2HDF6PJ.js.map +1 -0
- package/dist/{chunk-OFZGNWBT.js → chunk-ETREYN5U.js} +1 -1
- package/dist/{chunk-OFZGNWBT.js.map → chunk-ETREYN5U.js.map} +1 -1
- package/dist/{chunk-KBCA4GEZ.js → chunk-FP2TQJZP.js} +1 -1
- package/dist/{chunk-YJAH6DFY.js → chunk-G7WARJ3X.js} +1 -1
- package/dist/chunk-G7WARJ3X.js.map +1 -0
- package/dist/{chunk-Z4OUB4SJ.js → chunk-GLTCCDN5.js} +1 -1
- package/dist/{chunk-Z4OUB4SJ.js.map → chunk-GLTCCDN5.js.map} +1 -1
- package/dist/chunk-GVNTKCVF.js +1 -0
- package/dist/chunk-GVNTKCVF.js.map +1 -0
- package/dist/{chunk-Q6YDPREF.js → chunk-GZLD7RTK.js} +1 -1
- package/dist/{chunk-Q6YDPREF.js.map → chunk-GZLD7RTK.js.map} +1 -1
- package/dist/{chunk-SC4MEHVY.js → chunk-HIJR7DOC.js} +1 -1
- package/dist/{chunk-SC4MEHVY.js.map → chunk-HIJR7DOC.js.map} +1 -1
- package/dist/{chunk-ETWMPMZP.js → chunk-K5JK3XQB.js} +1 -1
- package/dist/{chunk-GRIK3EDH.js → chunk-KY7KSPU6.js} +1 -1
- package/dist/{chunk-GRIK3EDH.js.map → chunk-KY7KSPU6.js.map} +1 -1
- package/dist/{chunk-EHFHRQEP.js → chunk-M4STXLXO.js} +1 -1
- package/dist/{chunk-EHFHRQEP.js.map → chunk-M4STXLXO.js.map} +1 -1
- package/dist/{chunk-5YEHJM6V.js → chunk-OSMBAFRW.js} +1 -1
- package/dist/{chunk-5YEHJM6V.js.map → chunk-OSMBAFRW.js.map} +1 -1
- package/dist/chunk-PIU24HRN.js +1 -0
- package/dist/chunk-PIU24HRN.js.map +1 -0
- package/dist/{chunk-ELT3FEA4.js → chunk-PKKBYBL4.js} +1 -1
- package/dist/{chunk-ELT3FEA4.js.map → chunk-PKKBYBL4.js.map} +1 -1
- package/dist/{chunk-6HMIF2RJ.js → chunk-Q647OXON.js} +1 -1
- package/dist/{chunk-6HMIF2RJ.js.map → chunk-Q647OXON.js.map} +1 -1
- package/dist/{chunk-BMQM4JBL.js → chunk-QPT2WJYN.js} +1 -1
- package/dist/{chunk-BMQM4JBL.js.map → chunk-QPT2WJYN.js.map} +1 -1
- package/dist/{chunk-3WGXGBW5.js → chunk-R2AEZYX7.js} +1 -1
- package/dist/{chunk-FJIWJYKO.js → chunk-RA4YJBU5.js} +1 -1
- package/dist/chunk-RA4YJBU5.js.map +1 -0
- package/dist/{chunk-MRLUWHGI.js → chunk-RJ3ZLQRB.js} +1 -1
- package/dist/{chunk-MRLUWHGI.js.map → chunk-RJ3ZLQRB.js.map} +1 -1
- package/dist/chunk-SFEQXUIA.js +1 -0
- package/dist/{chunk-WV7QCDL5.js → chunk-SIL356HB.js} +1 -1
- package/dist/{chunk-WV7QCDL5.js.map → chunk-SIL356HB.js.map} +1 -1
- package/dist/{chunk-OLKOWR7S.js → chunk-SS7HVNP5.js} +1 -1
- package/dist/{chunk-OLKOWR7S.js.map → chunk-SS7HVNP5.js.map} +1 -1
- package/dist/chunk-TRGHPX2O.js +1 -0
- package/dist/chunk-TRGHPX2O.js.map +1 -0
- package/dist/{chunk-GMTAFUAG.js → chunk-TYRH73MO.js} +1 -1
- package/dist/{chunk-GMTAFUAG.js.map → chunk-TYRH73MO.js.map} +1 -1
- package/dist/{chunk-7TVFV3VO.js → chunk-U3IRMXMR.js} +1 -1
- package/dist/{chunk-A7IVMYNF.js → chunk-U73MBQ45.js} +1 -1
- package/dist/{chunk-A7IVMYNF.js.map → chunk-U73MBQ45.js.map} +1 -1
- package/dist/{chunk-IZIIGK3W.js → chunk-UE22QU7A.js} +1 -1
- package/dist/{chunk-IZIIGK3W.js.map → chunk-UE22QU7A.js.map} +1 -1
- package/dist/{chunk-DBDCOHI4.js → chunk-UI5RROGI.js} +1 -1
- package/dist/{chunk-DBDCOHI4.js.map → chunk-UI5RROGI.js.map} +1 -1
- package/dist/chunk-URRPEUIK.js +1 -0
- package/dist/{chunk-QJECDMQQ.js.map → chunk-URRPEUIK.js.map} +1 -1
- package/dist/chunk-UTWZZOSA.js +1 -0
- package/dist/chunk-UTWZZOSA.js.map +1 -0
- package/dist/chunk-UVX7RCMP.js +1 -0
- package/dist/chunk-UVX7RCMP.js.map +1 -0
- package/dist/{chunk-7ATBEOVC.js → chunk-WG4DPXJI.js} +1 -1
- package/dist/{chunk-XFDMCPDW.js → chunk-WZIBBJHA.js} +1 -1
- package/dist/{chunk-XFDMCPDW.js.map → chunk-WZIBBJHA.js.map} +1 -1
- package/dist/{chunk-7EWZGDWY.js → chunk-X3MXPE7G.js} +1 -1
- package/dist/{chunk-7EWZGDWY.js.map → chunk-X3MXPE7G.js.map} +1 -1
- package/dist/{chunk-JCYOE3C4.js → chunk-XQJERZUS.js} +1 -1
- package/dist/{chunk-JCYOE3C4.js.map → chunk-XQJERZUS.js.map} +1 -1
- package/dist/{chunk-SD6GNFDX.js → chunk-YBE5M27G.js} +1 -1
- package/dist/{chunk-SD6GNFDX.js.map → chunk-YBE5M27G.js.map} +1 -1
- package/dist/chunk-ZBUTGTZ3.js +1 -0
- package/dist/chunk-ZBUTGTZ3.js.map +1 -0
- package/dist/commodities/commodities-all.d.ts +2 -2
- package/dist/commodities/commodities-all.js +1 -1
- package/dist/commodities/commodities-rare.d.ts +3 -4
- package/dist/commodities/commodities-rare.js +1 -1
- package/dist/commodities/commodities-standard.d.ts +7 -7
- package/dist/commodities/commodities-standard.js +1 -1
- package/dist/commodities/commodities.d.ts +12 -12
- package/dist/commodities/commodities.js +1 -1
- package/dist/commodities/index.js +1 -1
- package/dist/equipment/engineering.d.ts +11 -6
- package/dist/equipment/engineering.js +1 -1
- package/dist/equipment/index.d.ts +4 -4
- package/dist/equipment/index.js +1 -1
- package/dist/equipment/modification-journal.js +1 -1
- package/dist/equipment/modifications.d.ts +23 -14
- package/dist/equipment/modifications.js +1 -1
- package/dist/equipment/suits.d.ts +2 -145
- package/dist/equipment/suits.js +1 -1
- package/dist/equipment/tools.d.ts +102 -0
- package/dist/equipment/tools.js +1 -0
- package/dist/equipment/tools.js.map +1 -0
- package/dist/equipment/upgrade-costs.d.ts +2 -3
- package/dist/equipment/upgrade-costs.js +1 -1
- package/dist/equipment/weapons.d.ts +2 -135
- package/dist/equipment/weapons.js +1 -1
- package/dist/i18n/blueprints.d.ts +2 -3
- package/dist/i18n/blueprints.js +1 -1
- package/dist/i18n/commodities.d.ts +36 -0
- package/dist/i18n/commodities.js +1 -0
- package/dist/i18n/commodities.js.map +1 -0
- package/dist/i18n/experimental-effect-descriptions.d.ts +5 -6
- package/dist/i18n/experimental-effect-descriptions.js +1 -1
- package/dist/i18n/experimental-effects.d.ts +2 -3
- package/dist/i18n/experimental-effects.js +1 -1
- package/dist/i18n/index.d.ts +19 -9
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/materials.d.ts +2 -4
- package/dist/i18n/materials.js +1 -1
- package/dist/i18n/micro-resources.d.ts +2 -4
- package/dist/i18n/micro-resources.js +1 -1
- package/dist/i18n/module-families.d.ts +3 -5
- package/dist/i18n/module-families.js +1 -1
- package/dist/i18n/modules.d.ts +3 -6
- package/dist/i18n/modules.js +1 -1
- package/dist/i18n/personal-modifications.d.ts +4 -6
- package/dist/i18n/personal-modifications.js +1 -1
- package/dist/i18n/personal-tools.d.ts +33 -0
- package/dist/i18n/personal-tools.js +1 -0
- package/dist/i18n/personal-tools.js.map +1 -0
- package/dist/i18n/personal-weapons.d.ts +3 -4
- package/dist/i18n/personal-weapons.js +1 -1
- package/dist/i18n/pre-engineered.d.ts +1 -1
- package/dist/i18n/slots.d.ts +2 -2
- package/dist/i18n/suits.d.ts +36 -6
- package/dist/i18n/suits.js +1 -1
- package/dist/materials/index.d.ts +4 -3
- package/dist/materials/index.js +1 -1
- package/dist/materials/materials-all.d.ts +2 -2
- package/dist/materials/materials-all.js +1 -1
- package/dist/materials/materials-raw.d.ts +3 -4
- package/dist/materials/materials-raw.js +1 -1
- package/dist/materials/materials.d.ts +18 -15
- package/dist/materials/materials.js +1 -1
- package/dist/materials/micro-resources-all.d.ts +2 -2
- package/dist/materials/micro-resources-all.js +1 -1
- package/dist/materials/micro-resources-component.d.ts +2 -2
- package/dist/materials/micro-resources-consumable.d.ts +2 -2
- package/dist/materials/micro-resources-data.d.ts +2 -2
- package/dist/materials/micro-resources-item.d.ts +2 -2
- package/dist/materials/micro-resources.d.ts +17 -14
- package/dist/materials/micro-resources.js +1 -1
- package/dist/ships/ammunition.d.ts +4 -4
- package/dist/ships/blueprint-costs.d.ts +13 -13
- package/dist/ships/blueprint-costs.js +1 -1
- package/dist/ships/blueprint-journal.d.ts +3 -3
- package/dist/ships/blueprint-journal.js +1 -1
- package/dist/ships/blueprints.d.ts +3 -3
- package/dist/ships/build-metrics.d.ts +2 -1
- package/dist/ships/build-metrics.js +1 -1
- package/dist/ships/default-loadouts.d.ts +2 -3
- package/dist/ships/default-loadouts.js +1 -1
- package/dist/ships/engineering-options.d.ts +29 -32
- package/dist/ships/engineering-options.js +1 -1
- package/dist/ships/engineering.d.ts +1 -2
- package/dist/ships/engineering.js +1 -1
- package/dist/ships/experimental-effect-costs.d.ts +1 -1
- package/dist/ships/gunsights.d.ts +3 -3
- package/dist/ships/heat.d.ts +1 -1
- package/dist/ships/index.d.ts +4 -5
- package/dist/ships/index.js +1 -1
- package/dist/ships/loadout-validation.d.ts +1 -1
- package/dist/ships/module-families.d.ts +1 -1
- package/dist/ships/modules-all.d.ts +2 -3
- package/dist/ships/modules-all.js +1 -1
- package/dist/ships/modules-core.d.ts +3 -3
- package/dist/ships/modules-hardpoint.d.ts +4 -5
- package/dist/ships/modules-hardpoint.js +1 -1
- package/dist/ships/modules-internal.d.ts +5 -6
- package/dist/ships/modules-internal.js +1 -1
- package/dist/ships/modules-utility.d.ts +3 -4
- package/dist/ships/modules-utility.js +1 -1
- package/dist/ships/modules.d.ts +26 -24
- package/dist/ships/modules.js +1 -1
- package/dist/ships/pre-engineered-stats.d.ts +1 -1
- package/dist/ships/pre-engineered-stats.js +1 -1
- package/dist/ships/pre-engineered.d.ts +9 -10
- package/dist/ships/pre-engineered.js +1 -1
- package/dist/ships/shield-capacitor.js +1 -1
- package/dist/ships/ship-loadout.d.ts +7 -7
- package/dist/ships/ship-loadout.js +1 -1
- package/dist/ships/ships.d.ts +1 -2
- package/dist/ships/ships.js +1 -1
- package/dist/ships/slots.d.ts +5 -5
- package/dist/ships/weapons.js +1 -1
- package/dist/suits-B37rAORs.d.ts +414 -0
- package/dist/{system-address-cyJaeZIS.d.ts → system-address-DmzXRD48.d.ts} +6 -4
- package/package.json +13 -1
- package/dist/chunk-77TT4K53.js +0 -1
- package/dist/chunk-DAQ3PJ4R.js +0 -1
- package/dist/chunk-DAQ3PJ4R.js.map +0 -1
- package/dist/chunk-DHACRCLI.js +0 -1
- package/dist/chunk-DHACRCLI.js.map +0 -1
- package/dist/chunk-FJIWJYKO.js.map +0 -1
- package/dist/chunk-IUSMAX5T.js +0 -1
- package/dist/chunk-IUSMAX5T.js.map +0 -1
- package/dist/chunk-LWNBWRKL.js +0 -1
- package/dist/chunk-LWNBWRKL.js.map +0 -1
- package/dist/chunk-MT5AHPNP.js +0 -1
- package/dist/chunk-MT5AHPNP.js.map +0 -1
- package/dist/chunk-QJECDMQQ.js +0 -1
- package/dist/chunk-YJAH6DFY.js.map +0 -1
- /package/dist/{chunk-XSLPWM5N.js.map → chunk-2J6NNI3Y.js.map} +0 -0
- /package/dist/{chunk-DWRNXUAX.js.map → chunk-2KIZN3BY.js.map} +0 -0
- /package/dist/{chunk-J7BM5NGK.js.map → chunk-2TY42PTF.js.map} +0 -0
- /package/dist/{chunk-KBCA4GEZ.js.map → chunk-FP2TQJZP.js.map} +0 -0
- /package/dist/{chunk-ETWMPMZP.js.map → chunk-K5JK3XQB.js.map} +0 -0
- /package/dist/{chunk-3WGXGBW5.js.map → chunk-R2AEZYX7.js.map} +0 -0
- /package/dist/{chunk-77TT4K53.js.map → chunk-SFEQXUIA.js.map} +0 -0
- /package/dist/{chunk-7TVFV3VO.js.map → chunk-U3IRMXMR.js.map} +0 -0
- /package/dist/{chunk-7ATBEOVC.js.map → chunk-WG4DPXJI.js.map} +0 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { PersonalModifier } from './equipment/engineering.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Odyssey handheld weapons: their journal identifiers, combat stats, sight
|
|
5
|
+
* magnification, reload time, grade-dependent damage, and the damage per second those
|
|
6
|
+
* stats resolve to.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** A weapon manufacturer's shared Pioneer grade-upgrade recipe. */
|
|
12
|
+
type WeaponUpgradeGroup = 'karma' | 'takada' | 'manticore';
|
|
13
|
+
/** Technology suffix used to disambiguate personal-weapon modification recipes. */
|
|
14
|
+
type PersonalWeaponEngineeringType = 'kinetic' | 'laser' | 'plasma';
|
|
15
|
+
/** A handheld weapon's form factor. */
|
|
16
|
+
type PersonalWeaponClass = 'pistol' | 'carbine' | 'rifle' | 'shotgun' | 'sniper' | 'launcher';
|
|
17
|
+
/** Which suit weapon slot accepts the weapon. */
|
|
18
|
+
type PersonalWeaponSlot = 'primary' | 'secondary';
|
|
19
|
+
/** The damage family relevant to resistances and some modification recipes. */
|
|
20
|
+
type PersonalDamageType = 'kinetic' | 'thermal' | 'plasma' | 'explosive';
|
|
21
|
+
/** A handheld weapon firing cycle. */
|
|
22
|
+
type PersonalFireMode = 'automatic' | 'semi-automatic' | 'burst';
|
|
23
|
+
/** A weapon's aim-down-sights magnification, before and after the Scope modification. */
|
|
24
|
+
interface ScopeMagnification {
|
|
25
|
+
/** Magnification of the sight the weapon ships with, e.g. `1.12` for 1.12x. */
|
|
26
|
+
readonly default: number;
|
|
27
|
+
/** Magnification of the sight the Scope modification fits, e.g. `1.41` for 1.41x. */
|
|
28
|
+
readonly upgraded: number;
|
|
29
|
+
}
|
|
30
|
+
/** A weapon's magazine reload time, before and after the Reload Speed modification. */
|
|
31
|
+
interface ReloadTime {
|
|
32
|
+
/** Seconds to reload the weapon as it ships, e.g. `2.7` for 2.7 s. */
|
|
33
|
+
readonly default: number;
|
|
34
|
+
/** Seconds to reload with the Reload Speed modification fitted, e.g. `2.16` for 2.16 s. */
|
|
35
|
+
readonly upgraded: number;
|
|
36
|
+
}
|
|
37
|
+
/** Grade-dependent stats for one handheld weapon. */
|
|
38
|
+
interface PersonalWeaponGrade {
|
|
39
|
+
/** Damage per projectile or pellet. */
|
|
40
|
+
readonly damage: number;
|
|
41
|
+
/** Permanent engineering-modification slots available, from `0` through `4`. */
|
|
42
|
+
readonly modificationSlots: number;
|
|
43
|
+
}
|
|
44
|
+
/** One handheld weapon sold by Pioneer Supplies. */
|
|
45
|
+
interface PersonalWeapon {
|
|
46
|
+
/** Frontier item id reported by journal loadout events. */
|
|
47
|
+
readonly symbol: string;
|
|
48
|
+
/** English display name. */
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/** Manufacturer recipe family used for grade upgrades. */
|
|
51
|
+
readonly upgradeGroup: WeaponUpgradeGroup;
|
|
52
|
+
/** Recipe suffix used when the journal omits a modification's weapon technology. */
|
|
53
|
+
readonly engineeringType: PersonalWeaponEngineeringType;
|
|
54
|
+
/** Weapon form factor. */
|
|
55
|
+
readonly class: PersonalWeaponClass;
|
|
56
|
+
/** Suit slot this weapon occupies. */
|
|
57
|
+
readonly slot: PersonalWeaponSlot;
|
|
58
|
+
/** Base damage family. */
|
|
59
|
+
readonly damageType: PersonalDamageType;
|
|
60
|
+
/** Firing cycle. */
|
|
61
|
+
readonly fireMode: PersonalFireMode;
|
|
62
|
+
/** Trigger pulls per second, so bursts per second on a burst weapon. */
|
|
63
|
+
readonly rateOfFire: number;
|
|
64
|
+
/**
|
|
65
|
+
* Projectiles one round fires, each doing the full
|
|
66
|
+
* {@link PersonalWeaponGrade.damage}. Absent on every weapon that fires a single
|
|
67
|
+
* projectile — only the Manticore Intimidator, a shotgun, carries it.
|
|
68
|
+
*/
|
|
69
|
+
readonly projectiles?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Rounds one trigger pull fires, spent from the magazine. Present only when
|
|
72
|
+
* {@link PersonalWeapon.fireMode} is `"burst"`, together with
|
|
73
|
+
* {@link PersonalWeapon.burstRateOfFire}.
|
|
74
|
+
*/
|
|
75
|
+
readonly burstRounds?: number;
|
|
76
|
+
/** Rounds per second within one burst. Absent whenever `burstRounds` is. */
|
|
77
|
+
readonly burstRateOfFire?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Rounds loaded in one magazine. A burst weapon spends
|
|
80
|
+
* {@link PersonalWeapon.burstRounds} of them per trigger pull.
|
|
81
|
+
*/
|
|
82
|
+
readonly magazineSize: number;
|
|
83
|
+
/** Spare rounds carried before suit-capacity changes. */
|
|
84
|
+
readonly reserveAmmo: number;
|
|
85
|
+
/** Headshot damage multiplier (`2` means 200%). */
|
|
86
|
+
readonly headshotMultiplier: number;
|
|
87
|
+
/** Nominal effective range in metres. */
|
|
88
|
+
readonly effectiveRange: number;
|
|
89
|
+
/**
|
|
90
|
+
* Aim-down-sights magnification with the stock sight and with the one the Scope
|
|
91
|
+
* modification fits. Scope carries no modifier of its own: this pair is its whole
|
|
92
|
+
* numeric effect, and it differs per weapon.
|
|
93
|
+
*/
|
|
94
|
+
readonly scopeMagnification: ScopeMagnification;
|
|
95
|
+
/**
|
|
96
|
+
* Seconds to reload the magazine with the stock weapon and with the Reload Speed
|
|
97
|
+
* modification fitted. Reload Speed carries no modifier of its own: this pair is its
|
|
98
|
+
* whole numeric effect, and it differs per weapon.
|
|
99
|
+
*/
|
|
100
|
+
readonly reloadTime: ReloadTime;
|
|
101
|
+
/**
|
|
102
|
+
* Grade records keyed by `"1"` through `"5"` — every weapon carries all five,
|
|
103
|
+
* unlike {@link Suit.grades}. Read one through
|
|
104
|
+
* {@link getPersonalWeaponGrade} to get the same nullable answer suits give.
|
|
105
|
+
*/
|
|
106
|
+
readonly grades: Readonly<Record<`${EquipmentGrade}`, PersonalWeaponGrade>>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Every handheld weapon, in catalogue order.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { PERSONAL_WEAPONS } from '@elite-dangerous-almanac/core/equipment/weapons';
|
|
114
|
+
* PERSONAL_WEAPONS[0]?.symbol; // -> 'wpn_s_pistol_kinetic_sauto'
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
declare const PERSONAL_WEAPONS: readonly PersonalWeapon[];
|
|
118
|
+
/**
|
|
119
|
+
* Look up a handheld weapon by its Frontier journal symbol, case-insensitively.
|
|
120
|
+
*
|
|
121
|
+
* @param symbol - Journal item id such as `"wpn_m_assaultrifle_kinetic_fauto"`,
|
|
122
|
+
* matched case-insensitively after trimming surrounding whitespace.
|
|
123
|
+
* @returns The frozen weapon record, or `null` when unknown.
|
|
124
|
+
* @throws {TypeError} If `symbol` is present and not a string. A nullish symbol is a
|
|
125
|
+
* miss, answered like an unrecognised one.
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { getPersonalWeaponBySymbol } from '@elite-dangerous-almanac/core/equipment/weapons';
|
|
129
|
+
* getPersonalWeaponBySymbol('wpn_m_assaultrifle_kinetic_fauto')?.name; // -> 'Karma AR-50'
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare function getPersonalWeaponBySymbol(symbol: string): PersonalWeapon | null;
|
|
133
|
+
/**
|
|
134
|
+
* Look up a handheld weapon by display name, case-insensitively.
|
|
135
|
+
*
|
|
136
|
+
* @param name - English display name such as `"Karma AR-50"`; surrounding
|
|
137
|
+
* whitespace is ignored.
|
|
138
|
+
* @returns The frozen weapon record, or `null` when unknown.
|
|
139
|
+
* @throws {TypeError} If `name` is present and not a string. A nullish name is a miss,
|
|
140
|
+
* answered like an unrecognised one.
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { getPersonalWeaponByName } from '@elite-dangerous-almanac/core/equipment/weapons';
|
|
144
|
+
* getPersonalWeaponByName('Karma AR-50')?.symbol; // -> 'wpn_m_assaultrifle_kinetic_fauto'
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function getPersonalWeaponByName(name: string): PersonalWeapon | null;
|
|
148
|
+
/**
|
|
149
|
+
* Read one handheld weapon's stats at a grade.
|
|
150
|
+
*
|
|
151
|
+
* @param weapon - A catalogue weapon record.
|
|
152
|
+
* @param grade - Integer grade `1`–`5`.
|
|
153
|
+
* @returns The frozen grade record, or `null` when the record carries no such grade.
|
|
154
|
+
* Every catalogued weapon carries all five, so the `null` is the same promise
|
|
155
|
+
* {@link getSuitGrade} makes rather than an outcome the shipped catalogue produces —
|
|
156
|
+
* write the two the same way and neither can surprise you.
|
|
157
|
+
* @throws {RangeError} If `grade` is not an integer from 1 through 5.
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { PERSONAL_WEAPONS, getPersonalWeaponGrade } from '@elite-dangerous-almanac/core/equipment/weapons';
|
|
161
|
+
* getPersonalWeaponGrade(PERSONAL_WEAPONS[0]!, 5)?.modificationSlots; // -> 4
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
declare function getPersonalWeaponGrade(weapon: PersonalWeapon, grade: number): PersonalWeaponGrade | null;
|
|
165
|
+
/**
|
|
166
|
+
* What one handheld weapon does per second at a grade, sustained and unsustained.
|
|
167
|
+
*
|
|
168
|
+
* @remarks
|
|
169
|
+
* Frozen, so a result can be held and shared without a defensive copy.
|
|
170
|
+
*/
|
|
171
|
+
interface PersonalWeaponMetrics {
|
|
172
|
+
/** Damage of one trigger pull — every projectile of every round in it. */
|
|
173
|
+
readonly damagePerShot: number;
|
|
174
|
+
/** {@link PersonalWeaponMetrics.damagePerShot} with every projectile hitting the head. */
|
|
175
|
+
readonly headshotDamagePerShot: number;
|
|
176
|
+
/** Trigger pulls per second. */
|
|
177
|
+
readonly rateOfFire: number;
|
|
178
|
+
/** Trigger pulls per second averaged over reloads. */
|
|
179
|
+
readonly sustainedRateOfFire: number;
|
|
180
|
+
/** Damage per second while firing, reloads ignored. */
|
|
181
|
+
readonly damagePerSecond: number;
|
|
182
|
+
/** Damage per second averaged over reloads — the figure a long fight sees. */
|
|
183
|
+
readonly sustainedDamagePerSecond: number;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Everything the on-foot damage arithmetic gives you for one weapon: damage per trigger
|
|
187
|
+
* pull, per second, and per second once reloads are counted.
|
|
188
|
+
*
|
|
189
|
+
* A grade record states damage **per projectile**, so a shot is that damage times the
|
|
190
|
+
* projectiles a round carries times the rounds one trigger pull fires. The sustained
|
|
191
|
+
* figures then average in the reload: a magazine's worth of fire takes the shots after
|
|
192
|
+
* the first, plus the tail of the last burst, plus the reload.
|
|
193
|
+
*
|
|
194
|
+
* ```text
|
|
195
|
+
* damagePerShot = damage × projectiles × burstRounds
|
|
196
|
+
* DPS = damagePerShot × rateOfFire
|
|
197
|
+
* SDPS = damagePerShot × (magazine's shots / one magazine-and-reload cycle)
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @param weapon - A catalogue weapon record.
|
|
201
|
+
* @param grade - Integer grade `1`–`5`.
|
|
202
|
+
* @param modifiers - Fitted modification modifiers, folded per stat the way
|
|
203
|
+
* {@link applyPersonalModifiers} does. `magazineSize` and `headshotMultiplier` are the
|
|
204
|
+
* two this arithmetic reads; modifiers naming other stats are ignored. A Reload Speed
|
|
205
|
+
* modification carries no modifier at all, so it arrives through `options` instead. A
|
|
206
|
+
* fractional magazine is held to whole rounds, rounding **up**, as `ships/weapons` does.
|
|
207
|
+
* @param options - `reloadSpeed` takes the reload from
|
|
208
|
+
* {@link PersonalWeapon.reloadTime | reloadTime.upgraded} rather than `.default`,
|
|
209
|
+
* because Reload Speed carries its magnitude as that pair rather than as a modifier.
|
|
210
|
+
* @returns The frozen {@link PersonalWeaponMetrics}, or `null` when the record carries
|
|
211
|
+
* no such grade — the same nullable answer {@link getPersonalWeaponGrade} gives. A
|
|
212
|
+
* magazine that modifiers empty to zero rounds or fewer reports no sustained fire.
|
|
213
|
+
* @throws {RangeError} If `grade` is not an integer from 1 through 5.
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* import {
|
|
217
|
+
* getPersonalWeaponByName,
|
|
218
|
+
* personalWeaponMetrics,
|
|
219
|
+
* } from '@elite-dangerous-almanac/core/equipment/weapons';
|
|
220
|
+
*
|
|
221
|
+
* const shotgun = getPersonalWeaponByName('Manticore Intimidator')!;
|
|
222
|
+
* personalWeaponMetrics(shotgun, 5)?.damagePerShot; // -> 52.15 (ten pellets of 5.215)
|
|
223
|
+
* personalWeaponMetrics(shotgun, 5)?.damagePerSecond; // -> 65.19
|
|
224
|
+
* personalWeaponMetrics(shotgun, 5)?.sustainedDamagePerSecond; // -> 31.6 (with the 2.5 s reload)
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
declare function personalWeaponMetrics(weapon: PersonalWeapon, grade: number, modifiers?: readonly PersonalModifier[], options?: {
|
|
228
|
+
readonly reloadSpeed?: boolean;
|
|
229
|
+
}): PersonalWeaponMetrics | null;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Odyssey personal suits: their journal identifiers, the suit-wide component stats every
|
|
233
|
+
* grade shares, and the grade-dependent defensive stats.
|
|
234
|
+
*
|
|
235
|
+
* @packageDocumentation
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
/** A Pioneer Supplies equipment grade, from the stock grade 1 through grade 5. */
|
|
239
|
+
type EquipmentGrade = 1 | 2 | 3 | 4 | 5;
|
|
240
|
+
/**
|
|
241
|
+
* Frontier's own `SlotName` for a suit weapon mount, exactly as the journal spells it.
|
|
242
|
+
*
|
|
243
|
+
* @remarks
|
|
244
|
+
* The `SuitLoadout`, `CreateSuitLoadout`, `SwitchSuitLoadout`, `LoadoutEquipModule` and
|
|
245
|
+
* `LoadoutRemoveModule` events all write one of these three strings. The secondary mount
|
|
246
|
+
* carries no number, because the game gives it none. Compare a key with `===`; it is
|
|
247
|
+
* case-sensitive, like every other journal key.
|
|
248
|
+
*/
|
|
249
|
+
type PersonalMountKey = 'PrimaryWeapon1' | 'PrimaryWeapon2' | 'SecondaryWeapon';
|
|
250
|
+
/**
|
|
251
|
+
* One weapon mount on a suit.
|
|
252
|
+
*
|
|
253
|
+
* @remarks
|
|
254
|
+
* {@link PersonalMount.key} is Frontier's journal `SlotName`, so a `SuitLoadout`
|
|
255
|
+
* module joins straight onto a mount without a positional index.
|
|
256
|
+
* @example
|
|
257
|
+
* ```ts
|
|
258
|
+
* import { getSuitByFamily } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
259
|
+
*
|
|
260
|
+
* const suit = getSuitByFamily('tacticalsuit')!;
|
|
261
|
+
* suit.mounts.map((mount) => mount.key);
|
|
262
|
+
* // -> ['PrimaryWeapon1', 'PrimaryWeapon2', 'SecondaryWeapon']
|
|
263
|
+
* suit.mounts.filter((mount) => mount.kind === 'primary').map((mount) => mount.key);
|
|
264
|
+
* // -> ['PrimaryWeapon1', 'PrimaryWeapon2']
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
interface PersonalMount {
|
|
268
|
+
/** Frontier journal `SlotName`, e.g. `"PrimaryWeapon1"`. */
|
|
269
|
+
readonly key: PersonalMountKey;
|
|
270
|
+
/** Which weapons the mount takes; a weapon whose `slot` equals it fits here. */
|
|
271
|
+
readonly kind: PersonalWeaponSlot;
|
|
272
|
+
}
|
|
273
|
+
/** The stats of one suit at one equipment grade. */
|
|
274
|
+
interface SuitGrade {
|
|
275
|
+
/** Frontier item symbol for this exact suit and grade. */
|
|
276
|
+
readonly symbol: string;
|
|
277
|
+
/** Permanent engineering-modification slots available, from `0` through `4`. */
|
|
278
|
+
readonly modificationSlots: number;
|
|
279
|
+
/** Base shield strength in shield points. */
|
|
280
|
+
readonly shieldStrength: number;
|
|
281
|
+
/** Shield points regenerated per second. */
|
|
282
|
+
readonly shieldRegeneration: number;
|
|
283
|
+
/** Kinetic damage resistance as a fraction; negative values increase damage. */
|
|
284
|
+
readonly kineticResistance: number;
|
|
285
|
+
/** Thermal damage resistance as a fraction. */
|
|
286
|
+
readonly thermalResistance: number;
|
|
287
|
+
/** Plasma damage resistance as a fraction; negative values increase damage. */
|
|
288
|
+
readonly plasmaResistance: number;
|
|
289
|
+
/** Explosive damage resistance as a fraction. */
|
|
290
|
+
readonly explosiveResistance: number;
|
|
291
|
+
}
|
|
292
|
+
/** One personal suit model sold by Pioneer Supplies. */
|
|
293
|
+
interface Suit {
|
|
294
|
+
/** Suit family without a grade suffix, e.g. `"utilitysuit"`. */
|
|
295
|
+
readonly family: string;
|
|
296
|
+
/** English display name, e.g. `"Maverick Suit"`. */
|
|
297
|
+
readonly name: string;
|
|
298
|
+
/**
|
|
299
|
+
* Every weapon mount the suit carries, in the order the game lists them: the
|
|
300
|
+
* primary mounts by their number, then the secondary mount.
|
|
301
|
+
*
|
|
302
|
+
* @remarks
|
|
303
|
+
* Count a kind by filtering:
|
|
304
|
+
* `suit.mounts.filter((mount) => mount.kind === 'primary').length`.
|
|
305
|
+
*/
|
|
306
|
+
readonly mounts: readonly PersonalMount[];
|
|
307
|
+
/** Suit health in health points, the pool the shield protects. */
|
|
308
|
+
readonly health: number;
|
|
309
|
+
/** Suit mass in kilograms. */
|
|
310
|
+
readonly mass: number;
|
|
311
|
+
/** Battery capacity in energy units, the pool the suit's tools draw from. */
|
|
312
|
+
readonly batteryCapacity: number;
|
|
313
|
+
/** Emergency air, in seconds of life support. */
|
|
314
|
+
readonly oxygenTime: number;
|
|
315
|
+
/** Jump-assist boost acceleration, the bare figure the panel shows, which has no unit. */
|
|
316
|
+
readonly boostAcceleration: number;
|
|
317
|
+
/** Backpack goods capacity in items. */
|
|
318
|
+
readonly goodsCapacity: number;
|
|
319
|
+
/** Backpack assets capacity in components. */
|
|
320
|
+
readonly assetsCapacity: number;
|
|
321
|
+
/** Backpack data capacity in items. */
|
|
322
|
+
readonly dataCapacity: number;
|
|
323
|
+
/** How far footsteps carry, as a multiplier of the base audible range. */
|
|
324
|
+
readonly footstepAudibleRange: number;
|
|
325
|
+
/** Line-of-sight analysis range in metres. */
|
|
326
|
+
readonly losAnalysisRange: number;
|
|
327
|
+
/** Seconds of line of sight the suit needs to complete an analysis. */
|
|
328
|
+
readonly losAnalysisTime: number;
|
|
329
|
+
/**
|
|
330
|
+
* Available grade records, keyed by `"1"` through `"5"`.
|
|
331
|
+
*
|
|
332
|
+
* @remarks
|
|
333
|
+
* A grade changes exactly what {@link SuitGrade} carries — the four resistances,
|
|
334
|
+
* shield strength, shield regeneration, the modification slots and the item symbol.
|
|
335
|
+
* Every stat above is a property of the suit family and is the same at all five.
|
|
336
|
+
*/
|
|
337
|
+
readonly grades: Readonly<Partial<Record<`${EquipmentGrade}`, SuitGrade>>>;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Every personal suit, including the non-upgradeable Flight Suit.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```ts
|
|
344
|
+
* import { SUITS } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
345
|
+
* SUITS.find((suit) => suit.family === 'utilitysuit')?.name; // -> 'Maverick Suit'
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
declare const SUITS: readonly Suit[];
|
|
349
|
+
/**
|
|
350
|
+
* Look up a suit model by its grade-independent family, case-insensitively.
|
|
351
|
+
*
|
|
352
|
+
* @param family - Family such as `"utilitysuit"`, matched case-insensitively after
|
|
353
|
+
* trimming surrounding whitespace.
|
|
354
|
+
* @returns The frozen suit record, or `null` when unknown.
|
|
355
|
+
* @throws {TypeError} If `family` is present and not a string. A nullish family is a
|
|
356
|
+
* miss, answered like an unrecognised one.
|
|
357
|
+
* @example
|
|
358
|
+
* ```ts
|
|
359
|
+
* import { getSuitByFamily } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
360
|
+
* getSuitByFamily('utilitysuit')?.name; // -> 'Maverick Suit'
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
declare function getSuitByFamily(family: string): Suit | null;
|
|
364
|
+
/**
|
|
365
|
+
* Look up a suit by its display name, case-insensitively.
|
|
366
|
+
*
|
|
367
|
+
* @param name - Display name such as `"Maverick Suit"`, matched case-insensitively
|
|
368
|
+
* after trimming surrounding whitespace.
|
|
369
|
+
* @returns The frozen suit record, or `null` when unknown.
|
|
370
|
+
* @throws {TypeError} If `name` is present and not a string. A nullish name is a miss,
|
|
371
|
+
* answered like an unrecognised one.
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* import { getSuitByName } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
375
|
+
* getSuitByName('Maverick Suit')?.family; // -> 'utilitysuit'
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
declare function getSuitByName(name: string): Suit | null;
|
|
379
|
+
/**
|
|
380
|
+
* Resolve the grade-specific Frontier item symbol reported by journal suit events.
|
|
381
|
+
*
|
|
382
|
+
* @param symbol - Item symbol such as `"utilitysuit_class3"`, matched
|
|
383
|
+
* case-insensitively after trimming surrounding whitespace.
|
|
384
|
+
* @returns The owning suit and its numeric grade, or `null` when unknown.
|
|
385
|
+
* @throws {TypeError} If `symbol` is present and not a string. A nullish symbol is a
|
|
386
|
+
* miss, answered like an unrecognised one.
|
|
387
|
+
* @example
|
|
388
|
+
* ```ts
|
|
389
|
+
* import { getSuitBySymbol } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
390
|
+
* getSuitBySymbol('utilitysuit_class3')?.grade; // -> 3
|
|
391
|
+
* ```
|
|
392
|
+
*/
|
|
393
|
+
declare function getSuitBySymbol(symbol: string): Readonly<{
|
|
394
|
+
suit: Suit;
|
|
395
|
+
grade: EquipmentGrade;
|
|
396
|
+
}> | null;
|
|
397
|
+
/**
|
|
398
|
+
* Read a suit's stats at one grade.
|
|
399
|
+
*
|
|
400
|
+
* @param suit - A catalogue suit record.
|
|
401
|
+
* @param grade - Integer grade `1`–`5`.
|
|
402
|
+
* @returns The frozen grade record, or `null` when that suit has no such grade.
|
|
403
|
+
* @throws {RangeError} If `grade` is not an integer from 1 through 5.
|
|
404
|
+
* @example
|
|
405
|
+
* ```ts
|
|
406
|
+
* import { getSuitByFamily, getSuitGrade } from '@elite-dangerous-almanac/core/equipment/suits';
|
|
407
|
+
* const suit = getSuitByFamily('utilitysuit');
|
|
408
|
+
* if (!suit) throw new Error('Maverick Suit is missing');
|
|
409
|
+
* getSuitGrade(suit, 5)?.modificationSlots; // -> 4
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
declare function getSuitGrade(suit: Suit, grade: number): SuitGrade | null;
|
|
413
|
+
|
|
414
|
+
export { type EquipmentGrade as E, PERSONAL_WEAPONS as P, type ReloadTime as R, SUITS as S, type WeaponUpgradeGroup as W, type PersonalDamageType as a, type PersonalFireMode as b, type PersonalMount as c, type PersonalMountKey as d, type PersonalWeapon as e, type PersonalWeaponClass as f, type PersonalWeaponEngineeringType as g, type PersonalWeaponGrade as h, type PersonalWeaponMetrics as i, type PersonalWeaponSlot as j, type ScopeMagnification as k, type Suit as l, type SuitGrade as m, getPersonalWeaponByName as n, getPersonalWeaponBySymbol as o, getPersonalWeaponGrade as p, getSuitByFamily as q, getSuitByName as r, getSuitBySymbol as s, getSuitGrade as t, personalWeaponMetrics as u };
|
|
@@ -271,8 +271,9 @@ declare function decodeModSystemAddress(id64: SystemAddressInput): DecodedAddres
|
|
|
271
271
|
* `resolveNamingRegionOrigin` in `./naming-region-origins`.
|
|
272
272
|
* @returns The 64-bit system address.
|
|
273
273
|
* @throws {RangeError} If the mass code is outside 0–7, a letter is outside 0–25, `n1`
|
|
274
|
-
* is not one the boxel packer accepts, the origin has a negative coordinate, the name's
|
|
275
|
-
* address layout, or the sequence does not fit
|
|
274
|
+
* is not one the boxel packer accepts, the origin has a negative coordinate, the name's
|
|
275
|
+
* boxel code or sector falls outside the address layout, or the sequence does not fit
|
|
276
|
+
* its size-class-dependent field.
|
|
276
277
|
* @example
|
|
277
278
|
* ```ts
|
|
278
279
|
* import { resolveNamingRegionOrigin } from '@elite-dangerous-almanac/core/astro/naming-region-origins';
|
|
@@ -297,8 +298,9 @@ declare function encodeSystemAddress(parts: SystemNameParts, origin: NamingRegio
|
|
|
297
298
|
* @returns The 64-bit modulated system address. These routinely exceed `2^53`, so
|
|
298
299
|
* keep them as `bigint` (or a decimal string) rather than a JS `number`.
|
|
299
300
|
* @throws {RangeError} If the mass code is outside 0–7, a letter is outside 0–25, `n1`
|
|
300
|
-
* is not one the boxel packer accepts, the origin has a negative coordinate, the name's
|
|
301
|
-
* address layout, or the sequence does not fit
|
|
301
|
+
* is not one the boxel packer accepts, the origin has a negative coordinate, the name's
|
|
302
|
+
* boxel code or sector falls outside the address layout, or the sequence does not fit
|
|
303
|
+
* the 15-bit modulated field.
|
|
302
304
|
* @example
|
|
303
305
|
* ```ts
|
|
304
306
|
* import { resolveNamingRegionOrigin } from '@elite-dangerous-almanac/core/astro/naming-region-origins';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elite-dangerous-almanac/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Elite Dangerous static data and calculations: astronomy, ships and outfitting, personal equipment and engineering, materials, and market commodities.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -190,6 +190,10 @@
|
|
|
190
190
|
"types": "./dist/equipment/suits.d.ts",
|
|
191
191
|
"import": "./dist/equipment/suits.js"
|
|
192
192
|
},
|
|
193
|
+
"./equipment/tools": {
|
|
194
|
+
"types": "./dist/equipment/tools.d.ts",
|
|
195
|
+
"import": "./dist/equipment/tools.js"
|
|
196
|
+
},
|
|
193
197
|
"./equipment/upgrade-costs": {
|
|
194
198
|
"types": "./dist/equipment/upgrade-costs.d.ts",
|
|
195
199
|
"import": "./dist/equipment/upgrade-costs.js"
|
|
@@ -215,6 +219,10 @@
|
|
|
215
219
|
"types": "./dist/i18n/experimental-effect-descriptions.d.ts",
|
|
216
220
|
"import": "./dist/i18n/experimental-effect-descriptions.js"
|
|
217
221
|
},
|
|
222
|
+
"./i18n/commodities": {
|
|
223
|
+
"types": "./dist/i18n/commodities.d.ts",
|
|
224
|
+
"import": "./dist/i18n/commodities.js"
|
|
225
|
+
},
|
|
218
226
|
"./i18n/diagnostics": {
|
|
219
227
|
"types": "./dist/i18n/diagnostics.d.ts",
|
|
220
228
|
"import": "./dist/i18n/diagnostics.js"
|
|
@@ -240,6 +248,10 @@
|
|
|
240
248
|
"types": "./dist/i18n/personal-modifications.d.ts",
|
|
241
249
|
"import": "./dist/i18n/personal-modifications.js"
|
|
242
250
|
},
|
|
251
|
+
"./i18n/personal-tools": {
|
|
252
|
+
"types": "./dist/i18n/personal-tools.d.ts",
|
|
253
|
+
"import": "./dist/i18n/personal-tools.js"
|
|
254
|
+
},
|
|
243
255
|
"./i18n/personal-weapons": {
|
|
244
256
|
"types": "./dist/i18n/personal-weapons.d.ts",
|
|
245
257
|
"import": "./dist/i18n/personal-weapons.js"
|
package/dist/chunk-77TT4K53.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{RARE_COMMODITIES}from"./chunk-GMTAFUAG.js";import{COMMODITIES}from"./chunk-6HMIF2RJ.js";var ALL_COMMODITIES=Object.freeze([...COMMODITIES,...RARE_COMMODITIES]);export{ALL_COMMODITIES};//# sourceMappingURL=chunk-77TT4K53.js.map
|
package/dist/chunk-DAQ3PJ4R.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{COMPONENT_MICRO_RESOURCES}from"./chunk-HTB52N6S.js";import{CONSUMABLE_MICRO_RESOURCES}from"./chunk-K7L7SMIR.js";import{DATA_MICRO_RESOURCES}from"./chunk-GVLDFJEY.js";import{ITEM_MICRO_RESOURCES}from"./chunk-WHWFKHV3.js";var ALL_MICRO_RESOURCES=Object.freeze([...COMPONENT_MICRO_RESOURCES,...CONSUMABLE_MICRO_RESOURCES,...DATA_MICRO_RESOURCES,...ITEM_MICRO_RESOURCES]);export{ALL_MICRO_RESOURCES};//# sourceMappingURL=chunk-DAQ3PJ4R.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/materials/micro-resources-all.ts"],"names":["COMPONENT_MICRO_RESOURCES","CONSUMABLE_MICRO_RESOURCES","DATA_MICRO_RESOURCES","ITEM_MICRO_RESOURCES","ALL_MICRO_RESOURCES","Object","freeze"],"mappings":"O,4NA6BO,IAAMI,oBAAgDC,OAAOC,OAAO,IACpEN,6BACAC,8BACAC,wBACAC,8BACNC"}
|
package/dist/chunk-DHACRCLI.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{weaponMetrics}from"./chunk-2OBUSQA7.js";import{shieldMetrics}from"./chunk-5VWACBTN.js";import{getShipBySymbol,getShipByName,getShipSlots}from"./chunk-6UNAD74Z.js";import{getLoadoutModifier}from"./chunk-T4MKUKYS.js";import{sourcePurchaseFromLoadout}from"./chunk-NIURLW2F.js";import{isBuiltInHullSymbol,identifyPreEngineeredVariant,unrollableFixedArticle,cloneLoadoutModule,isNonOutfittingSlot,isBuiltInHullModule,matchingKeyIn,ownKeyIn,getPreEngineeredStats,getPreEngineeredModifiers,cloneModuleStats,isFinalGuardianWeaponEngineering,scaleDamageComponents}from"./chunk-IN36YSS4.js";import{builtInModuleBySymbol,getBulkheadsForShip}from"./chunk-5YEHJM6V.js";import{getPreEngineeredVariants}from"./chunk-BJU27V6C.js";import{stockedMountKind}from"./chunk-M6J7KP7G.js";import{CORE_MODULES}from"./chunk-ZZTDEDXJ.js";import{getExperimentalEffect}from"./chunk-77I24V6B.js";import{fieldForLabel,scaleForLabel,labelsForField,capabilityValueForLabel,damageTypeForLabel}from"./chunk-A7IVMYNF.js";import{BURST_PATTERN_LABELS,journalRateOfFire,preciseValueFor}from"./chunk-EFQOUATZ.js";import{getDefaultLoadout}from"./chunk-GRIK3EDH.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{parseSlotName,SLOT_RESTRICTION_LABELS,enumerateSlots}from"./chunk-RAO35XDF.js";import{normalizeKey}from"./chunk-BKWLI44T.js";import{truncate,requireString,describeValue,requireStringIfPresent}from"./chunk-PKWVG2JY.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var MILITARY_PREFIXES=["int_hullreinforcement","int_metaalloyhullreinforcement","int_modulereinforcement","int_shieldcellbank","int_guardianhullreinforcement","int_guardianmodulereinforcement","int_guardianshieldreinforcement"];var MINING_PREFIXES=["hpt_mininglaser","hpt_mining_abrblstr","hpt_mining_seismchrgwarhd","hpt_mining_subsurfdispmisle","hpt_human_extraction","hpt_miningtoolv2"];var CARGO_PREFIXES=["int_cargorack","int_largecargorack","int_corrosionproofcargorack","int_fueltank"];var RESTRICTED_SLOT_PREFIXES={mining:MINING_PREFIXES,military:MILITARY_PREFIXES,cargo:CARGO_PREFIXES,limpetController:["int_dronecontrol","int_multidronecontrol"],vesselHangar:["int_fighterbay"],passenger:["int_passengercabin","int_mkii_passengercabin"],planetaryApproachSuite:["int_planetapproachsuite"]};var problem=(constraint,message,params)=>({constraint:constraint,message:message,...params===void 0?{}:{params:params}});function restrictionProblem(slot,symbol){const restriction=slot.restriction;if(!restriction)return null;if(RESTRICTED_SLOT_PREFIXES[restriction].some(prefix=>symbol.startsWith(prefix))){return null}return problem("restrictedMount",`slot only takes ${SLOT_RESTRICTION_LABELS[restriction]}`,{restriction:restriction})}function moduleSlotProblem(slot,module){const required=module.restrictedToSlot;if(!required||slot.restriction===required)return null;return problem("restrictedMount",`module only fits a mount that takes ${SLOT_RESTRICTION_LABELS[required]}`,{restriction:required})}function moduleFitProblem(shipSymbol,slot,module){if(slot.kind==="cargoHatch"){return problem("immutableSlot","the cargoHatch slot cannot be changed")}if(isBuiltInHullSymbol(module.symbol)){return problem("builtInHullModule","the cargo hatch is part of the hull, not an outfitting module")}if(slot.kind==="armour"){const hull=getShipBySymbol(shipSymbol);if(module.slot!=="armour"||module.ship===void 0){return problem("armourRequired","not a ship armour module")}if(!hull||module.ship.toLowerCase()!==hull.name.toLowerCase()){const armourHull=getShipByName(module.ship);return problem("wrongHullArmour",`armour belongs to ${truncate(module.ship)}, not ${truncate(hull?.name??shipSymbol)}`,{armourShipName:module.ship,...armourHull===null?{}:{armourShipSymbol:armourHull.symbol},shipSymbol:shipSymbol,...hull===null?{}:{shipName:hull.name}})}return null}const restricted=module.restrictedToShips;if(restricted&&!restricted.some(symbol2=>symbol2.toLowerCase()===shipSymbol.toLowerCase())){const allowedShipNames=restricted.map(symbol2=>{const hull=getShipBySymbol(symbol2);return hull?.name??symbol2});const labels=restricted.map((symbol2,index)=>{const name=allowedShipNames[index];return name===symbol2?symbol2:`${name} (${symbol2})`});return problem("restrictedHull",`module is restricted to ${truncate(labels.join(", "))}`,{allowedShipNames:allowedShipNames,allowedShipSymbols:[...restricted],shipSymbol:shipSymbol})}const wrongMount=moduleSlotProblem(slot,module);if(wrongMount)return wrongMount;const symbol=module.symbol.toLowerCase();const moduleSlot=module.slot;switch(slot.kind){case"core":if(moduleSlot!==slot.core){return problem("wrongCoreType",`not a ${slot.core} module`,{requiredCore:slot.core,moduleSlot:moduleSlot??"none"})}break;case"hardpoint":{if(module.category!=="hardpoint"){return problem("hardpointRequired","not a hardpoint weapon")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}case"utility":if(module.category!=="utility"){return problem("utilityRequired","not a utility module")}return null;case"optional":{const isFuelTank=moduleSlot==="fuelTank";if(module.category!=="internal"&&!isFuelTank){return problem("optionalInternalRequired","not an optional-internal module")}if(moduleSlot&&!isFuelTank){return problem("coreModuleInOptionalSlot","a core module only fits its core slot")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}}return module.class>slot.size?problem("oversized",`module size ${truncate(module.class)} exceeds slot size ${slot.size}`,{moduleClass:module.class,slotSize:slot.size}):null}function moduleFitError(shipSymbol,slot,module){return moduleFitProblem(shipSymbol,slot,module)?.message??null}function preEngineeredVariantFor(module){return identifyPreEngineeredVariant(module)??(module.Engineering?unrollableFixedArticle(module.Item,module.Engineering):null)}function captureLoadoutEvent(event){const modules=event.Modules;const shipName=event.ShipName;const shipIdent=event.ShipIdent;const hullValue=event.HullValue;const modulesValue=event.ModulesValue;const rebuy=event.Rebuy;const unladenMass=event.UnladenMass;const cargoCapacity=event.CargoCapacity;const fuelCapacity=event.FuelCapacity;return{Ship:event.Ship,Modules:Array.isArray(modules)?captureEach(modules,captureModule):modules,...shipName===void 0?{}:{ShipName:shipName},...shipIdent===void 0?{}:{ShipIdent:shipIdent},...hullValue===void 0?{}:{HullValue:hullValue},...modulesValue===void 0?{}:{ModulesValue:modulesValue},...rebuy===void 0?{}:{Rebuy:rebuy},...unladenMass===void 0?{}:{UnladenMass:unladenMass},...cargoCapacity===void 0?{}:{CargoCapacity:cargoCapacity},...fuelCapacity===void 0?{}:{FuelCapacity:{...fuelCapacity}}}}function captureEach(values,capture){const captured=[];const{length:length}=values;for(let index=0;index<length;index++)captured.push(capture(values[index]));return captured}function captureModule(module){if(module===null||typeof module!=="object")return module;const on=module.On;const priority=module.Priority;const health=module.Health;const value=module.Value;const engineering=module.Engineering;return{Slot:module.Slot,Item:module.Item,...on===void 0?{}:{On:on},...priority===void 0?{}:{Priority:priority},...health===void 0?{}:{Health:health},...value===void 0?{}:{Value:value},...engineering===void 0?{}:{Engineering:captureEngineering(engineering)}}}function captureEngineering(engineering){if(engineering===null||typeof engineering!=="object")return engineering;const experimental=engineering.ExperimentalEffect;const experimentalLocalised=engineering.ExperimentalEffect_Localised;const modifiers=engineering.Modifiers;return{BlueprintName:engineering.BlueprintName,Level:engineering.Level,Quality:engineering.Quality,...experimental===void 0?{}:{ExperimentalEffect:experimental},...experimentalLocalised===void 0?{}:{ExperimentalEffect_Localised:experimentalLocalised},...modifiers===void 0?{}:{Modifiers:Array.isArray(modifiers)?captureEach(modifiers,modifier=>modifier!==null&&typeof modifier==="object"?{...modifier}:modifier):modifiers}}}function hullLayout(shipSymbol){const slots=getShipSlots(shipSymbol);return slots?enumerateSlots(slots):[]}function stockedMountRejects(shipSymbol,layout,slot,stats){const mount=layout.find(candidate=>candidate.key.toLowerCase()===slot.toLowerCase());return mount!==void 0&&moduleFitProblem(shipSymbol,mount,stats)!==null}function normalizeLoadoutEvent(rawEvent){const event=captureLoadoutEvent(rawEvent);requireString(event.Ship,"ShipLoadout.fromLoadout: event.Ship");if(!Array.isArray(event.Modules)){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules must be an array, received ${describeValue(event.Modules)}`)}const modules=/* @__PURE__ */new Map;const slots=/* @__PURE__ */new Set;for(const module of event.Modules){if(module===null||typeof module!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules[] must hold module objects, received ${describeValue(module)}`)}requireString(module.Slot,"ShipLoadout.fromLoadout: module.Slot");requireString(module.Item,"ShipLoadout.fromLoadout: module.Item");if(module.Engineering!==void 0){if(module.Engineering===null||typeof module.Engineering!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering must be an object, received ${describeValue(module.Engineering)}`)}requireStringIfPresent(module.Engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");requireStringIfPresent(module.Engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");if(module.Engineering.Modifiers!==void 0&&!Array.isArray(module.Engineering.Modifiers)){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers must be an array, received ${describeValue(module.Engineering.Modifiers)}`)}for(const[index,modifier]of(module.Engineering.Modifiers??[]).entries()){if(modifier===null||typeof modifier!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}] must be an object, received ${describeValue(modifier)}`)}requireString(modifier.Label,`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}].Label`)}}const normalizedSlot=module.Slot.toLowerCase();if(slots.has(normalizedSlot)){throw new TypeError(`ShipLoadout.fromLoadout: duplicate slot "${truncate(module.Slot)}"`)}slots.add(normalizedSlot);modules.set(module.Slot,cloneLoadoutModule(module))}const top={};if(event.ShipName!==void 0)top.ShipName=event.ShipName;if(event.ShipIdent!==void 0)top.ShipIdent=event.ShipIdent;if(event.HullValue!==void 0)top.HullValue=event.HullValue;if(event.ModulesValue!==void 0)top.ModulesValue=event.ModulesValue;if(event.Rebuy!==void 0)top.Rebuy=event.Rebuy;if(event.UnladenMass!==void 0)top.UnladenMass=event.UnladenMass;if(event.CargoCapacity!==void 0)top.CargoCapacity=event.CargoCapacity;if(event.FuelCapacity!==void 0)top.FuelCapacity={...event.FuelCapacity};let invalidatesAggregates=false;const outcomes=[];const defaults=getDefaultLoadout(event.Ship)?.modules??[];let layout;for(const[slot,module]of modules){if(isNonOutfittingSlot(slot)||isBuiltInHullModule(module))continue;const stats=builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");const parsed=parseSlotName(slot);const stocked=parsed===null?null:stockedMountKind(parsed);const fallback=stocked===null?void 0:defaults.find(candidate=>candidate.slot.toLowerCase()===slot.toLowerCase());const rejected=fallback!==void 0&&(stats===null||stocked==="cargoHatch"||stockedMountRejects(event.Ship,layout??=hullLayout(event.Ship),slot,stats));if(stats!==null&&!rejected)continue;if(fallback){modules.set(slot,{Slot:slot,Item:fallback.symbol,...module.On===void 0?{}:{On:module.On},...module.Priority===void 0?{}:{Priority:module.Priority},...module.Health===void 0?{}:{Health:module.Health}});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:module.Item,replacementSymbol:fallback.symbol})}else{modules.delete(slot);outcomes.push({action:"emptied",slot:slot,sourceSymbol:module.Item})}invalidatesAggregates=true}for(const fallback of defaults){const parsed=parseSlotName(fallback.slot);const stocked=parsed===null?null:stockedMountKind(parsed);if(stocked===null||matchingKeyIn(modules,fallback.slot)!==null)continue;const slot=ownKeyIn(modules,fallback.slot);modules.set(slot,{Slot:slot,Item:fallback.symbol});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:null,replacementSymbol:fallback.symbol});if(stocked==="core")invalidatesAggregates=true}if(invalidatesAggregates){delete top.ModulesValue;delete top.Rebuy;delete top.UnladenMass;delete top.CargoCapacity;delete top.FuelCapacity}const moduleStats=/* @__PURE__ */new Map;const primitiveModifiers=/* @__PURE__ */new Map;for(const module of modules.values()){const engineering=module.Engineering;const variant=preEngineeredVariantFor(module);const catalogueVariantStats=variant?getPreEngineeredStats(variant):null;let variantStats=catalogueVariantStats;const retainsBakedExperimental=variant?.experimentalEffectSymbol!==void 0&&typeof engineering?.ExperimentalEffect==="string"&&variant.experimentalEffectSymbol.trim().toLowerCase()===engineering.ExperimentalEffect.trim().toLowerCase();if(variant&&catalogueVariantStats&&!catalogueVariantStats.engineeringLocked&&!retainsBakedExperimental){const{experimentalEffectSymbol:originalExperimental,...withoutExperimental}=variant;const currentExperimental=engineering?.ExperimentalEffect;const currentVariant=typeof currentExperimental==="string"?{...withoutExperimental,experimentalEffectSymbol:currentExperimental}:withoutExperimental;variantStats=getPreEngineeredStats(withoutExperimental);primitiveModifiers.set(module.Slot,[...engineering?.Modifiers??[],...getPreEngineeredModifiers(currentVariant)])}if(variantStats)moduleStats.set(module.Slot,cloneModuleStats(variantStats));const guardianFinal=typeof engineering?.BlueprintName==="string"&&isFinalGuardianWeaponEngineering(module.Item,engineering.BlueprintName);if(variantStats?.engineeringLocked||typeof engineering?.BlueprintName!=="string"||!guardianFinal){continue}const normalizedBlueprint=normalizeKey(engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");const normalizedExperimental=normalizeKey(engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");const variants=getPreEngineeredVariants(module.Item);const exact=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol?.toLowerCase()===normalizedExperimental);const guardianBase=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol===void 0);const stats=exact?getPreEngineeredStats(exact):guardianBase&&engineering.ExperimentalEffect!==void 0?getPreEngineeredStats({...guardianBase,experimentalEffectSymbol:engineering.ExperimentalEffect}):builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");if(stats){moduleStats.set(module.Slot,cloneModuleStats({...stats,engineeringLocked:true}))}}return{shipSymbol:event.Ship,modules:modules,moduleStats:moduleStats,primitiveModifiers:primitiveModifiers,top:top,sourcePurchase:sourcePurchaseFromLoadout(event),outcomes:deepFreeze(outcomes)}}var NO_ISSUES=Object.freeze([]);function completeResult(value){return Object.freeze({value:value,complete:true,issues:NO_ISSUES})}function incompleteResult(issues){return Object.freeze({value:null,complete:false,issues:Object.freeze(issues.map(issue=>Object.freeze({...issue,...issue.params?{params:Object.freeze({...issue.params})}:{}})))})}var PREFIX={powerPlant:["int_powerplant","int_guardianpowerplant"],thrusters:["int_engine","int_mkiiagileboost_engine"],frameShiftDrive:["int_hyperdrive"],powerDistributor:["int_powerdistributor","int_guardianpowerdistributor"],shieldGenerator:["int_shieldgenerator"],shieldCellBank:["int_shieldcellbank"],shieldBooster:["hpt_shieldbooster"],shieldReinforcement:["int_guardianshieldreinforcement"],hullReinforcement:["int_hullreinforcement","int_guardianhullreinforcement","int_metaalloyhullreinforcement"],moduleReinforcement:["int_modulereinforcement","int_guardianmodulereinforcement"]};var startsWithAny=(symbol,prefixes)=>prefixes.some(prefix=>symbol.toLowerCase().startsWith(prefix));function isPowerDistributor(module,stats){return stats?.slot?stats.slot==="powerDistributor":startsWithAny(module.Item,PREFIX.powerDistributor)}function isPowerPlant(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="powerPlant")return true;return stats?.slot?stats.slot==="powerPlant":startsWithAny(module.Item,PREFIX.powerPlant)}function isThruster(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="thrusters")return true;return stats?.slot?stats.slot==="thrusters":startsWithAny(module.Item,PREFIX.thrusters)}function isFrameShiftDrive(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="frameShiftDrive")return true;return stats?.slot?stats.slot==="frameShiftDrive":startsWithAny(module.Item,PREFIX.frameShiftDrive)}function isEnabled(module){return module.On!==false}function priorityOf(module){return(module.Priority??0)+1}function effectiveStat(module,field,stats){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base:void 0}function statedModifier(module,field){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)!==null)continue;const modified=getLoadoutModifier(module,label);if(modified!==null)return modified/scaleForLabel(label)}return void 0}function effectiveCapability(module,field,stats){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)===null)continue;if(module.Engineering?.Modifiers?.some(modifier=>modifier.Label.toLowerCase()===label.toLowerCase())){return true}}const base=stats[field];return typeof base==="boolean"?base:void 0}function effectiveDamageDistribution(module,stats){const fromEffect=module.Engineering?.ExperimentalEffect?getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution:void 0;const distribution={...fromEffect??stats.damageDistribution};let resolved=fromEffect!==void 0||stats.damageDistribution!==void 0;const seen=/* @__PURE__ */new Set;for(const modifier of module.Engineering?.Modifiers??[]){const type=damageTypeForLabel(modifier.Label);if(type===null||seen.has(type))continue;seen.add(type);if(modifier.Value===void 0)continue;distribution[type]=modifier.Value/scaleForLabel(modifier.Label);resolved=true}return resolved?distribution:void 0}function convertsDamage(module){if(module.Engineering?.ExperimentalEffect&&getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution){return true}return(module.Engineering?.Modifiers??[]).some(modifier=>damageTypeForLabel(modifier.Label)!==null)}function modifierRatio(module,stats,field){const base=stats?.[field];if(typeof base!=="number"||base===0)return 1;const effective=effectiveStat(module,field,stats);return effective===void 0?1:effective/base}function relatedStat(module,stats,field,ratio){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base*ratio:void 0}function effectiveModule(module,stats){if(!stats||!module.Engineering)return stats;const merged={...stats};const fields=new Set(Object.keys(stats));for(const modifier of module.Engineering.Modifiers??[]){const field=fieldForLabel(modifier.Label,stats);if(field)fields.add(field)}for(const key of fields){const capability=effectiveCapability(module,key,stats);if(capability!==void 0){merged[key]=capability;continue}const value=effectiveStat(module,key,stats);if(value!==void 0)merged[key]=value}if(stats.engineeringGroup==="thrusters"){const massRatio=modifierRatio(module,stats,"optMass");const minMass=relatedStat(module,stats,"minMass",massRatio);const maxMass=relatedStat(module,stats,"maxMass",massRatio);if(minMass!==void 0)merged.minMass=minMass;if(maxMass!==void 0)merged.maxMass=maxMass}if(stats.engineeringGroup==="thrusters"||stats.engineeringGroup==="shieldGenerators"){const performanceRatio=modifierRatio(module,stats,"optMultiplier");const minMultiplier=relatedStat(module,stats,"minMultiplier",performanceRatio);const maxMultiplier=relatedStat(module,stats,"maxMultiplier",performanceRatio);if(minMultiplier!==void 0)merged.minMultiplier=minMultiplier;if(maxMultiplier!==void 0)merged.maxMultiplier=maxMultiplier;if(stats.engineeringGroup==="thrusters"){for(const field of["minSpeedMultiplier","optSpeedMultiplier","maxSpeedMultiplier","minRotationMultiplier","optRotationMultiplier","maxRotationMultiplier"]){const value=stats[field];if(value!==void 0)merged[field]=value*performanceRatio}}}const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)merged.damageDistribution=damageDistribution;if(stats.category==="hardpoint")normalizeEffectiveWeapon(module,merged);if(convertsDamage(module)){delete merged.damageComponents}else if(stats.damageComponents){merged.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof merged.damage==="number"?merged.damage:void 0)}return merged}function powerConsumerFor(module,stats){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return null;const mounted=stats?.category==="hardpoint"||stats?.category==="utility";return{draw:draw,priority:priorityOf(module),enabled:isEnabled(module),deployedOnly:mounted&&stats?.alwaysPowered!==true,label:module.Slot,symbol:module.Item}}function powerAvailable(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return 0;return effectiveStat(module,"powerCapacity",stats)??0}return 0}var DEFAULT_SLOT={powerCapacity:"PowerPlant",heatEfficiency:"PowerPlant",thrusters:"MainEngines",powerDistributor:"PowerDistributor"};var UNRESOLVED_FACT={thrusters:"thruster stats",shieldGenerator:"shield-generator stats",powerCapacity:"power capacity",heatEfficiency:"heat efficiency",powerDistributor:"power-distributor stats"};var NOTHING_FITTED={powerCapacity:"PowerPlant: no power plant is fitted",heatEfficiency:"PowerPlant: no power plant is fitted",thrusters:"MainEngines: no thrusters are fitted",powerDistributor:"PowerDistributor: no power distributor is fitted"};function metricIssue(field,reason,module){const defaultSlot=DEFAULT_SLOT[field];const slot=module?.Slot??defaultSlot;const symbol=module?.Item;const params={field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol}};let message;if(reason==="missing"){message=NOTHING_FITTED[field]??"no shield generator is fitted"}else if(reason==="unresolved"){const unavailable=UNRESOLVED_FACT[field]??field;message=`${truncate(slot??field)}: ${unavailable} unavailable for ${truncate(symbol??field)}`}else if(reason==="disabled"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} is switched off`}else if(reason==="invalid"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} has invalid ${field}`}else{message=`${truncate(slot??field)}: ${truncate(symbol??field)} is not powered with hardpoints retracted`}return{field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol},message:message,params:params}}function powerPlantIssueFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return metricIssue("powerCapacity","disabled",module);const capacity=effectiveStat(module,"powerCapacity",stats);if(capacity===void 0)return metricIssue("powerCapacity","unresolved",module);return!Number.isFinite(capacity)||capacity<=0?metricIssue("powerCapacity","invalid",module):null}return metricIssue("powerCapacity","missing")}function powerDrawIssueFor(modules,statsFor){for(const module of modules){const consumer=powerConsumerFor(module,statsFor(module));if(consumer&&(!Number.isFinite(consumer.draw)||consumer.draw<0)){return metricIssue("powerDraw","invalid",module)}}return null}function poweredMetricBudgetFor(field,module,stats,modules,getBudget,statsFor){if(!isEnabled(module))return incompleteResult([metricIssue(field,"disabled",module)]);const plantIssue=powerPlantIssueFor(modules,statsFor);if(plantIssue)return incompleteResult([plantIssue]);const drawIssue=powerDrawIssueFor(modules,statsFor);if(drawIssue)return incompleteResult([drawIssue]);const budget=getBudget();return budget.available>0&&poweredStates(module,stats,budget).retracted?completeResult(budget):incompleteResult([metricIssue(field,"shed",module)])}function poweredShieldGeneratorResultFor(modules,getBudget,statsFor){for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldGenerator))continue;const stats=statsFor(module);const powered=poweredMetricBudgetFor("shieldGenerator",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;return stats===null?incompleteResult([metricIssue("shieldGenerator","unresolved",module)]):completeResult({module:module,budget:powered.value})}return incompleteResult([metricIssue("shieldGenerator","missing")])}function mapResistanceFields(read){return{kineticResistance:read("kineticResistance")??0,thermalResistance:read("thermalResistance")??0,explosiveResistance:read("explosiveResistance")??0,causticResistance:read("causticResistance")??0}}function resistancesOf(module,stats){return mapResistanceFields(field=>effectiveStat(module,field,stats))}function shieldInputFor(ship,modules,budget,statsFor){let generator=null;const boosters=[];let reinforcement=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!(budget.available>0&&poweredStates(module,stats,budget).retracted))continue;if(!generator&&startsWithAny(module.Item,PREFIX.shieldGenerator)){const massRatio=modifierRatio(module,stats,"optMass");const strengthRatio=modifierRatio(module,stats,"optMultiplier");const optMass=effectiveStat(module,"optMass",stats);const minMass=relatedStat(module,stats,"minMass",massRatio);const maxMass=relatedStat(module,stats,"maxMass",Math.max(1,massRatio));const optMultiplier=effectiveStat(module,"optMultiplier",stats);const minMultiplier=relatedStat(module,stats,"minMultiplier",strengthRatio);const maxMultiplier=relatedStat(module,stats,"maxMultiplier",strengthRatio);generator={...optMass===void 0?{}:{optMass:optMass},...minMass===void 0?{}:{minMass:minMass},...maxMass===void 0?{}:{maxMass:maxMass},...optMultiplier===void 0?{}:{optMultiplier:optMultiplier},...minMultiplier===void 0?{}:{minMultiplier:minMultiplier},...maxMultiplier===void 0?{}:{maxMultiplier:maxMultiplier},...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.shieldBooster)){boosters.push({shieldBoost:effectiveStat(module,"shieldBoost",stats)??0,...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.shieldReinforcement)){reinforcement+=effectiveStat(module,"shieldAddition",stats)??0}}return{hullMass:ship.hullMass,baseShieldStrength:ship.baseShieldStrength,generator:generator,boosters:boosters,reinforcement:reinforcement}}function shieldInputResultFor(ship,modules,getBudget,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;return completeResult(shieldInputFor(ship,modules,fitted.value.budget,statsFor))}function shieldCapacitorInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;const budget=fitted.value.budget;const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const shields=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor));return completeResult({strength:shields.strength,resistances:shields.resistances,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function systemsCapacitorResultFor(modules,budget,statsFor){let distributor=null;for(const module of modules){const stats2=statsFor(module);if(isPowerDistributor(module,stats2)&&isEnabled(module)&&budget.available>0&&poweredStates(module,stats2,budget).retracted)distributor=module}if(!distributor)return completeResult({systemsCapacity:0,systemsRecharge:0});const stats=statsFor(distributor);const systemsCapacity=effectiveStat(distributor,"systemsCapacity",stats);const systemsRecharge=effectiveStat(distributor,"systemsRecharge",stats);return systemsCapacity===void 0||systemsRecharge===void 0?incompleteResult([metricIssue("powerDistributor","unresolved",distributor)]):completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge})}function thrusterCurveFor(module,stats){const effective=effectiveModule(module,stats);const minMass=effective?.minMass;const optMass=effective?.optMass;const maxMass=effective?.maxMass;const minMultiplier=effective?.minMultiplier;const optMultiplier=effective?.optMultiplier;const maxMultiplier=effective?.maxMultiplier;if(minMass===void 0||optMass===void 0||maxMass===void 0||minMultiplier===void 0||optMultiplier===void 0||maxMultiplier===void 0){return null}return{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:minMultiplier,optMultiplier:optMultiplier,maxMultiplier:maxMultiplier,...effective?.optSpeedMultiplier===void 0?{}:{speedCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minSpeedMultiplier??minMultiplier,optMultiplier:effective.optSpeedMultiplier,maxMultiplier:effective.maxSpeedMultiplier??maxMultiplier}},...effective?.optRotationMultiplier===void 0?{}:{rotationCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minRotationMultiplier??minMultiplier,optMultiplier:effective.optRotationMultiplier,maxMultiplier:effective.maxRotationMultiplier??maxMultiplier}}}}function fittedThrusterParamsFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(isThruster(module,stats))return thrusterCurveFor(module,stats)}return null}function mobilityInputResultFor(ship,modules,getBudget,mass,statsFor){let thrusters=null;for(const module of modules){const stats=statsFor(module);if(!isThruster(module,stats))continue;const powered=poweredMetricBudgetFor("thrusters",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;thrusters=thrusterCurveFor(module,stats);if(!thrusters)return incompleteResult([metricIssue("thrusters","unresolved",module)]);break}if(!thrusters)return incompleteResult([metricIssue("thrusters","missing")]);return completeResult({minimumSpeed:ship.minimumSpeed,maximumSpeed:ship.maximumSpeed,boost:ship.boost,minPitch:ship.minPitch,pitch:ship.pitch,minRoll:ship.minRoll,roll:ship.roll,minYaw:ship.minYaw,yaw:ship.yaw,mass:typeof mass==="function"?mass():mass,thrusters:thrusters})}function shieldRecoveryInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const generator=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!generator.complete)return generator;const{module:generatorModule,budget:budget}=generator.value;const generatorStats=statsFor(generatorModule);const distributorDraw=effectiveStat(generatorModule,"distributorDraw",generatorStats);const regenRate=effectiveStat(generatorModule,"shieldRegenRate",generatorStats);const brokenRegenRate=effectiveStat(generatorModule,"shieldBrokenRegenRate",generatorStats);if(distributorDraw===void 0||regenRate===void 0||brokenRegenRate===void 0){return incompleteResult([metricIssue("shieldGenerator","unresolved",generatorModule)])}const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const strength=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor)).strength;return completeResult({strength:strength,regenRate:regenRate,brokenRegenRate:brokenRegenRate,distributorDraw:distributorDraw,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function weaponsCapacitorInputFor(modules,weaponsPips,budget,statsFor){let weaponsCapacity=0;let weaponsRecharge=0;let sustainedEnergyPerSecond=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!poweredStates(module,stats,budget).deployed)continue;if(isPowerDistributor(module,stats)){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0;weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats)??0}const weapon=weaponStatsFor(module,stats);if(weapon){sustainedEnergyPerSecond+=weaponMetrics(weapon).sustainedEnergyPerSecond}}return{weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,sustainedEnergyPerSecond:sustainedEnergyPerSecond,weaponsPips:weaponsPips}}function distributorInputResultFor(modules,pips,budget,statsFor){let disabled=null;for(const module of modules){const stats=statsFor(module);if(!isPowerDistributor(module,stats))continue;if(!isEnabled(module)){disabled??=module;continue}if(!poweredStates(module,stats,budget).retracted){return incompleteResult([metricIssue("powerDistributor","shed",module)])}const systemsCapacity=effectiveStat(module,"systemsCapacity",stats);const systemsRecharge=effectiveStat(module,"systemsRecharge",stats);const enginesCapacity=effectiveStat(module,"enginesCapacity",stats);const enginesRecharge=effectiveStat(module,"enginesRecharge",stats);const weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats);const weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats);if(systemsCapacity===void 0||systemsRecharge===void 0||enginesCapacity===void 0||enginesRecharge===void 0||weaponsCapacity===void 0||weaponsRecharge===void 0){return incompleteResult([metricIssue("powerDistributor","unresolved",module)])}return completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge,enginesCapacity:enginesCapacity,enginesRecharge:enginesRecharge,weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,...pips})}return incompleteResult([disabled===null?metricIssue("powerDistributor","missing"):metricIssue("powerDistributor","disabled",disabled)])}function heatInputResultFor(ship,modules,budget,statsFor){let plant=null;let heatEfficiency;let thrusterHeatRate=0;let deployedThrusterHeatRate=0;let fsdHeatRate=0;let weaponsCapacity=0;const weapons=[];for(const module of modules){const stats=statsFor(module);if(isPowerPlant(module,stats)){if(!isEnabled(module)){return incompleteResult([metricIssue("powerCapacity","disabled",module)])}plant=module;heatEfficiency=effectiveStat(module,"heatEfficiency",stats);continue}if(!isEnabled(module))continue;const running=poweredStates(module,stats,budget);if(isThruster(module,stats)){const heat=effectiveStat(module,"engineHeatRate",stats)??0;if(running.retracted)thrusterHeatRate+=heat;if(running.deployed)deployedThrusterHeatRate+=heat}else if(isFrameShiftDrive(module,stats)){if(running.retracted)fsdHeatRate+=effectiveStat(module,"fsdHeatRate",stats)??0}else if(isPowerDistributor(module,stats)){if(running.deployed){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0}}const weapon=weaponStatsFor(module,stats);if(!running.deployed)continue;if(!weapon)continue;weapons.push({heatPerSecond:weaponMetrics(weapon).sustainedHeatPerSecond,distributorDraw:weapon.distributorDraw??0})}if(heatEfficiency===void 0){return incompleteResult([plant===null?metricIssue("powerCapacity","missing"):metricIssue("heatEfficiency","unresolved",plant)])}return completeResult({heatCapacity:ship.heatCapacity,heatDissipation:ship.heatDissipation,heatEfficiency:heatEfficiency,retractedPowerDraw:poweredDraw(budget,"retracted"),deployedPowerDraw:poweredDraw(budget,"deployed"),thrusterHeatRate:thrusterHeatRate,deployedThrusterHeatRate:deployedThrusterHeatRate,fsdHeatRate:fsdHeatRate,weaponsCapacity:weaponsCapacity,weapons:weapons})}function poweredDraw(budget,state){const powered=state==="retracted"?"poweredRetracted":"poweredDeployed";return budget.bands.reduce((total,band)=>band[powered]?total+band[state]:total,0)}function poweredStates(module,stats,budget){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return{retracted:true,deployed:true};const band=budget.bands[Math.min(budget.bands.length,Math.max(1,priorityOf(module)))-1];if(!band)return{retracted:true,deployed:true};return{retracted:band.poweredRetracted,deployed:band.poweredDeployed}}function cellBankInputsFor(modules,budget,statsFor){const banks=[];for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldCellBank))continue;const stats=statsFor(module);const effective=effectiveModule(module,stats);const ammunition=effective?ammunitionCapacity(effective):null;banks.push({slot:module.Slot,symbol:module.Item,reinforcementRate:effective?.shieldBankReinforcement??0,cells:ammunition?.total??0,spinUp:effective?.shieldBankSpinUp??0,duration:effective?.shieldBankDuration??0,heat:effective?.shieldBankHeat??0,powered:budget.available>0&&isEnabled(module)&&poweredStates(module,stats,budget).deployed})}return banks}function stockBulkhead(ship){const variants=getBulkheadsForShip(ship.name,CORE_MODULES);return variants.find(v=>v.symbol.toLowerCase().endsWith("_default"))??variants.find(v=>v.mass===0)??variants[0]??null}function armourInputFor(ship,modules,statsFor){const reinforcements=[];const moduleReinforcements=[];let bulkhead=null;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(module.Slot.toLowerCase()==="armour"){bulkhead={hullBoost:effectiveStat(module,"hullBoost",stats)??0,...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.hullReinforcement)){const boost=getLoadoutModifier(module,"DefenceModifierHealthMultiplier");reinforcements.push({hullReinforcement:effectiveStat(module,"hullReinforcement",stats)??0,hullBoost:boost===null?0:boost/scaleForLabel("DefenceModifierHealthMultiplier"),...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.moduleReinforcement)){moduleReinforcements.push({moduleProtection:effectiveStat(module,"moduleProtection",stats)??0,integrity:effectiveStat(module,"integrity",stats)??0})}}if(!bulkhead){const stock=stockBulkhead(ship);bulkhead=stock?{hullBoost:stock.hullBoost??0,...mapResistanceFields(field=>stock[field])}:null}return{baseArmour:ship.baseArmour,bulkhead:bulkhead,reinforcements:reinforcements,moduleReinforcements:moduleReinforcements}}var WEAPON_FIELDS=["damage","roundsPerShot","rateOfFire","burstInterval","burstRounds","burstRateOfFire","chargeTime","clipSize","ammoMaximum","reloadTime","distributorDraw","thermalLoad","powerDraw","maximumRange","falloffRange","armourPiercing"];function weaponStatsFor(module,stats){if(!stats||stats.category!=="hardpoint")return null;const weapon={};for(const field of WEAPON_FIELDS){const value=effectiveStat(module,field,stats);if(value!==void 0)weapon[field]=value}normalizeEffectiveWeapon(module,weapon);const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)weapon.damageDistribution=damageDistribution;if(stats.damageComponents&&!convertsDamage(module)){weapon.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof weapon.damage==="number"?weapon.damage:void 0)}if(stats.projectileRange)weapon.projectileRange={...stats.projectileRange};return weapon}function burstAdjustedRateOfFire(module,weapon){if(getLoadoutModifier(module,"RateOfFire")!==null)return void 0;const modifiers=module.Engineering?.Modifiers;const touched=BURST_PATTERN_LABELS.some(label=>getLoadoutModifier(module,label)!==null);if(!touched)return void 0;const stated=(label,field)=>preciseValueFor(modifiers,label)??weapon[field];return journalRateOfFire(stated("BurstInterval","burstInterval"),stated("BurstSize","burstRounds"),stated("BurstRateOfFire","burstRateOfFire"))}var FIRING_RATE_LABELS=["RateOfFire","BurstRateOfFire","BurstSize","BurstInterval","RoundsPerShot","Rounds"];function readsDamageFromPerSecond(module){return getLoadoutModifier(module,"Damage")===null&&FIRING_RATE_LABELS.every(label=>getLoadoutModifier(module,label)===null)}function normalizeEffectiveWeapon(module,weapon){const rate=burstAdjustedRateOfFire(module,weapon);if(rate!==void 0)weapon.rateOfFire=rate;if(readsDamageFromPerSecond(module)){const statedDamagePerSecond=getLoadoutModifier(module,"DamagePerSecond");const firingFactor=Number(weapon.roundsPerShot??1)*Number(weapon.rateOfFire??1);if(statedDamagePerSecond!==null&&firingFactor>0){weapon.damage=statedDamagePerSecond/firingFactor}}const{maximumRange:maximumRange,falloffRange:falloffRange}=weapon;if(maximumRange!==void 0&&falloffRange!==void 0&&falloffRange>maximumRange){weapon.falloffRange=maximumRange}}var INTERNALS=/* @__PURE__ */new WeakMap;function publishLoadoutInternals(build,internals){INTERNALS.set(build,internals)}function loadoutInternals(build,label){const internals=typeof build==="object"&&build!==null?INTERNALS.get(build):void 0;if(internals===void 0){throw new TypeError(`${label} must be a ShipLoadout, received ${describeValue(build)}`)}return internals}export{armourInputFor,cellBankInputsFor,completeResult,distributorInputResultFor,effectiveModule,fittedThrusterParamsFor,heatInputResultFor,incompleteResult,loadoutInternals,mobilityInputResultFor,moduleFitError,moduleFitProblem,normalizeLoadoutEvent,powerAvailable,powerConsumerFor,preEngineeredVariantFor,publishLoadoutInternals,shieldCapacitorInputResultFor,shieldInputResultFor,shieldRecoveryInputResultFor,weaponStatsFor,weaponsCapacitorInputFor};//# sourceMappingURL=chunk-DHACRCLI.js.map
|