@elite-dangerous-almanac/core 0.1.0-beta.1
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/LICENSE +48 -0
- package/PROVENANCE/SNAPSHOTS.md +36 -0
- package/PROVENANCE/astro/SOURCES.md +94 -0
- package/PROVENANCE/commodities/SOURCES.md +41 -0
- package/PROVENANCE/materials/SOURCES.md +69 -0
- package/PROVENANCE/ships/SOURCES.md +1580 -0
- package/README.md +148 -0
- package/THIRD_PARTY_NOTICES.md +202 -0
- package/dist/astro/codex-region-lookup.d.ts +169 -0
- package/dist/astro/codex-region-lookup.js +1 -0
- package/dist/astro/codex-region-lookup.js.map +1 -0
- package/dist/astro/codex-region.d.ts +149 -0
- package/dist/astro/codex-region.js +1 -0
- package/dist/astro/codex-region.js.map +1 -0
- package/dist/astro/galaxy-grid.d.ts +83 -0
- package/dist/astro/galaxy-grid.js +1 -0
- package/dist/astro/galaxy-grid.js.map +1 -0
- package/dist/astro/hand-authored-regions.d.ts +121 -0
- package/dist/astro/hand-authored-regions.js +1 -0
- package/dist/astro/hand-authored-regions.js.map +1 -0
- package/dist/astro/index.d.ts +140 -0
- package/dist/astro/index.js +1 -0
- package/dist/astro/index.js.map +1 -0
- package/dist/astro/mass-code.d.ts +55 -0
- package/dist/astro/mass-code.js +1 -0
- package/dist/astro/mass-code.js.map +1 -0
- package/dist/astro/naming-region-origins.d.ts +4 -0
- package/dist/astro/naming-region-origins.js +1 -0
- package/dist/astro/naming-region-origins.js.map +1 -0
- package/dist/astro/nebulae-all.d.ts +40 -0
- package/dist/astro/nebulae-all.js +1 -0
- package/dist/astro/nebulae-all.js.map +1 -0
- package/dist/astro/nebulae-planetary.d.ts +37 -0
- package/dist/astro/nebulae-planetary.js +1 -0
- package/dist/astro/nebulae-planetary.js.map +1 -0
- package/dist/astro/nebulae-procgen.d.ts +36 -0
- package/dist/astro/nebulae-procgen.js +1 -0
- package/dist/astro/nebulae-procgen.js.map +1 -0
- package/dist/astro/nebulae-real.d.ts +37 -0
- package/dist/astro/nebulae-real.js +1 -0
- package/dist/astro/nebulae-real.js.map +1 -0
- package/dist/astro/nebulae.d.ts +169 -0
- package/dist/astro/nebulae.js +1 -0
- package/dist/astro/nebulae.js.map +1 -0
- package/dist/astro/permit-locked-regions.d.ts +54 -0
- package/dist/astro/permit-locked-regions.js +1 -0
- package/dist/astro/permit-locked-regions.js.map +1 -0
- package/dist/astro/permit-locked-systems.d.ts +74 -0
- package/dist/astro/permit-locked-systems.js +1 -0
- package/dist/astro/permit-locked-systems.js.map +1 -0
- package/dist/astro/permit-locks.d.ts +130 -0
- package/dist/astro/permit-locks.js +1 -0
- package/dist/astro/permit-locks.js.map +1 -0
- package/dist/astro/procedural-system.d.ts +228 -0
- package/dist/astro/procedural-system.js +1 -0
- package/dist/astro/procedural-system.js.map +1 -0
- package/dist/astro/sector-name.d.ts +87 -0
- package/dist/astro/sector-name.js +1 -0
- package/dist/astro/sector-name.js.map +1 -0
- package/dist/astro/system-address-input.d.ts +76 -0
- package/dist/astro/system-address-input.js +1 -0
- package/dist/astro/system-address-input.js.map +1 -0
- package/dist/astro/system-address.d.ts +4 -0
- package/dist/astro/system-address.js +1 -0
- package/dist/astro/system-address.js.map +1 -0
- package/dist/astro/system-name.d.ts +187 -0
- package/dist/astro/system-name.js +1 -0
- package/dist/astro/system-name.js.map +1 -0
- package/dist/chunk-2FHHMYDC.js +1 -0
- package/dist/chunk-2FHHMYDC.js.map +1 -0
- package/dist/chunk-462OKHXR.js +1 -0
- package/dist/chunk-462OKHXR.js.map +1 -0
- package/dist/chunk-5H74FKY7.js +1 -0
- package/dist/chunk-5H74FKY7.js.map +1 -0
- package/dist/chunk-6LUEKHO5.js +1 -0
- package/dist/chunk-6LUEKHO5.js.map +1 -0
- package/dist/chunk-76XKY2Y2.js +1 -0
- package/dist/chunk-76XKY2Y2.js.map +1 -0
- package/dist/chunk-7EE5VIHR.js +1 -0
- package/dist/chunk-7EE5VIHR.js.map +1 -0
- package/dist/chunk-A3NM7SAJ.js +1 -0
- package/dist/chunk-A3NM7SAJ.js.map +1 -0
- package/dist/chunk-A6XPYSVR.js +1 -0
- package/dist/chunk-A6XPYSVR.js.map +1 -0
- package/dist/chunk-AA3K5XUE.js +1 -0
- package/dist/chunk-AA3K5XUE.js.map +1 -0
- package/dist/chunk-AVZI6VKA.js +1 -0
- package/dist/chunk-AVZI6VKA.js.map +1 -0
- package/dist/chunk-B5TT26XE.js +1 -0
- package/dist/chunk-B5TT26XE.js.map +1 -0
- package/dist/chunk-BNILZXJD.js +1 -0
- package/dist/chunk-BNILZXJD.js.map +1 -0
- package/dist/chunk-BRDQUJXV.js +1 -0
- package/dist/chunk-BRDQUJXV.js.map +1 -0
- package/dist/chunk-BTPV5CIF.js +1 -0
- package/dist/chunk-BTPV5CIF.js.map +1 -0
- package/dist/chunk-CI3ACMRA.js +1 -0
- package/dist/chunk-CI3ACMRA.js.map +1 -0
- package/dist/chunk-COE5ADYJ.js +1 -0
- package/dist/chunk-COE5ADYJ.js.map +1 -0
- package/dist/chunk-CWAX3BSH.js +1 -0
- package/dist/chunk-CWAX3BSH.js.map +1 -0
- package/dist/chunk-DACZE3HX.js +1 -0
- package/dist/chunk-DACZE3HX.js.map +1 -0
- package/dist/chunk-DURKO7JU.js +1 -0
- package/dist/chunk-DURKO7JU.js.map +1 -0
- package/dist/chunk-E45EDCYH.js +1 -0
- package/dist/chunk-E45EDCYH.js.map +1 -0
- package/dist/chunk-ELIZXUMI.js +1 -0
- package/dist/chunk-ELIZXUMI.js.map +1 -0
- package/dist/chunk-EYGVDJ2I.js +1 -0
- package/dist/chunk-EYGVDJ2I.js.map +1 -0
- package/dist/chunk-FGXWVFN6.js +1 -0
- package/dist/chunk-FGXWVFN6.js.map +1 -0
- package/dist/chunk-GJCB2Z72.js +1 -0
- package/dist/chunk-GJCB2Z72.js.map +1 -0
- package/dist/chunk-HI7FCS3G.js +1 -0
- package/dist/chunk-HI7FCS3G.js.map +1 -0
- package/dist/chunk-HKXXFIRI.js +1 -0
- package/dist/chunk-HKXXFIRI.js.map +1 -0
- package/dist/chunk-HTB52N6S.js +1 -0
- package/dist/chunk-HTB52N6S.js.map +1 -0
- package/dist/chunk-I7PIDRMU.js +1 -0
- package/dist/chunk-I7PIDRMU.js.map +1 -0
- package/dist/chunk-IH4NXKVW.js +1 -0
- package/dist/chunk-IH4NXKVW.js.map +1 -0
- package/dist/chunk-INNFH37U.js +1 -0
- package/dist/chunk-INNFH37U.js.map +1 -0
- package/dist/chunk-J2PNZQY4.js +1 -0
- package/dist/chunk-J2PNZQY4.js.map +1 -0
- package/dist/chunk-JQG4C67D.js +1 -0
- package/dist/chunk-JQG4C67D.js.map +1 -0
- package/dist/chunk-JTQVWIGL.js +1 -0
- package/dist/chunk-JTQVWIGL.js.map +1 -0
- package/dist/chunk-JWJ7RSZC.js +1 -0
- package/dist/chunk-JWJ7RSZC.js.map +1 -0
- package/dist/chunk-K3AMV27L.js +1 -0
- package/dist/chunk-K3AMV27L.js.map +1 -0
- package/dist/chunk-K7F6WC4T.js +1 -0
- package/dist/chunk-K7F6WC4T.js.map +1 -0
- package/dist/chunk-K7L7SMIR.js +1 -0
- package/dist/chunk-K7L7SMIR.js.map +1 -0
- package/dist/chunk-KG4EWDZZ.js +1 -0
- package/dist/chunk-KG4EWDZZ.js.map +1 -0
- package/dist/chunk-KMFUCORC.js +1 -0
- package/dist/chunk-KMFUCORC.js.map +1 -0
- package/dist/chunk-L2ZZXEZM.js +1 -0
- package/dist/chunk-L2ZZXEZM.js.map +1 -0
- package/dist/chunk-L747RVPO.js +1 -0
- package/dist/chunk-L747RVPO.js.map +1 -0
- package/dist/chunk-MFV4VZFP.js +1 -0
- package/dist/chunk-MFV4VZFP.js.map +1 -0
- package/dist/chunk-NWPK6Q3S.js +1 -0
- package/dist/chunk-NWPK6Q3S.js.map +1 -0
- package/dist/chunk-PMJG7PHU.js +1 -0
- package/dist/chunk-PMJG7PHU.js.map +1 -0
- package/dist/chunk-PP2VSA6M.js +1 -0
- package/dist/chunk-PP2VSA6M.js.map +1 -0
- package/dist/chunk-Q22LXT53.js +1 -0
- package/dist/chunk-Q22LXT53.js.map +1 -0
- package/dist/chunk-Q5MR36RW.js +1 -0
- package/dist/chunk-Q5MR36RW.js.map +1 -0
- package/dist/chunk-Q5XOGATC.js +1 -0
- package/dist/chunk-Q5XOGATC.js.map +1 -0
- package/dist/chunk-QTDBO7R2.js +1 -0
- package/dist/chunk-QTDBO7R2.js.map +1 -0
- package/dist/chunk-R4OD62HV.js +1 -0
- package/dist/chunk-R4OD62HV.js.map +1 -0
- package/dist/chunk-RD73TFGS.js +1 -0
- package/dist/chunk-RD73TFGS.js.map +1 -0
- package/dist/chunk-RIT6MOO5.js +1 -0
- package/dist/chunk-RIT6MOO5.js.map +1 -0
- package/dist/chunk-RVSXKQHE.js +1 -0
- package/dist/chunk-RVSXKQHE.js.map +1 -0
- package/dist/chunk-S4DBNX2B.js +1 -0
- package/dist/chunk-S4DBNX2B.js.map +1 -0
- package/dist/chunk-S4UWCHL6.js +1 -0
- package/dist/chunk-S4UWCHL6.js.map +1 -0
- package/dist/chunk-SQS7672E.js +1 -0
- package/dist/chunk-SQS7672E.js.map +1 -0
- package/dist/chunk-TLNHETGC.js +1 -0
- package/dist/chunk-TLNHETGC.js.map +1 -0
- package/dist/chunk-U6TMCYA6.js +1 -0
- package/dist/chunk-U6TMCYA6.js.map +1 -0
- package/dist/chunk-V4C6FIE2.js +1 -0
- package/dist/chunk-V4C6FIE2.js.map +1 -0
- package/dist/chunk-VXVUEF5U.js +1 -0
- package/dist/chunk-VXVUEF5U.js.map +1 -0
- package/dist/chunk-VZXL5KBR.js +1 -0
- package/dist/chunk-VZXL5KBR.js.map +1 -0
- package/dist/chunk-VZZ2XIRE.js +1 -0
- package/dist/chunk-VZZ2XIRE.js.map +1 -0
- package/dist/chunk-WV5YM7H5.js +1 -0
- package/dist/chunk-WV5YM7H5.js.map +1 -0
- package/dist/chunk-Y2MUIE5W.js +1 -0
- package/dist/chunk-Y2MUIE5W.js.map +1 -0
- package/dist/chunk-Z43DN4PY.js +1 -0
- package/dist/chunk-Z43DN4PY.js.map +1 -0
- package/dist/chunk-Z4GTTB7I.js +1 -0
- package/dist/chunk-Z4GTTB7I.js.map +1 -0
- package/dist/chunk-Z4OUB4SJ.js +1 -0
- package/dist/chunk-Z4OUB4SJ.js.map +1 -0
- package/dist/chunk-ZFT56QFR.js +1 -0
- package/dist/chunk-ZFT56QFR.js.map +1 -0
- package/dist/chunk-ZNCXENNB.js +1 -0
- package/dist/chunk-ZNCXENNB.js.map +1 -0
- package/dist/commodities/commodities-all.d.ts +25 -0
- package/dist/commodities/commodities-all.js +1 -0
- package/dist/commodities/commodities-all.js.map +1 -0
- package/dist/commodities/commodities-rare.d.ts +34 -0
- package/dist/commodities/commodities-rare.js +1 -0
- package/dist/commodities/commodities-rare.js.map +1 -0
- package/dist/commodities/commodities-standard.d.ts +34 -0
- package/dist/commodities/commodities-standard.js +1 -0
- package/dist/commodities/commodities-standard.js.map +1 -0
- package/dist/commodities/commodities.d.ts +142 -0
- package/dist/commodities/commodities.js +1 -0
- package/dist/commodities/commodities.js.map +1 -0
- package/dist/commodities/index.d.ts +30 -0
- package/dist/commodities/index.js +1 -0
- package/dist/commodities/index.js.map +1 -0
- package/dist/galactic-position-shLkm4Qg.d.ts +30 -0
- package/dist/materials/index.d.ts +47 -0
- package/dist/materials/index.js +1 -0
- package/dist/materials/index.js.map +1 -0
- package/dist/materials/materials-all.d.ts +26 -0
- package/dist/materials/materials-all.js +1 -0
- package/dist/materials/materials-all.js.map +1 -0
- package/dist/materials/materials-encoded.d.ts +31 -0
- package/dist/materials/materials-encoded.js +1 -0
- package/dist/materials/materials-encoded.js.map +1 -0
- package/dist/materials/materials-manufactured.d.ts +32 -0
- package/dist/materials/materials-manufactured.js +1 -0
- package/dist/materials/materials-manufactured.js.map +1 -0
- package/dist/materials/materials-raw.d.ts +31 -0
- package/dist/materials/materials-raw.js +1 -0
- package/dist/materials/materials-raw.js.map +1 -0
- package/dist/materials/materials.d.ts +277 -0
- package/dist/materials/materials.js +1 -0
- package/dist/materials/materials.js.map +1 -0
- package/dist/materials/micro-resources-all.d.ts +28 -0
- package/dist/materials/micro-resources-all.js +1 -0
- package/dist/materials/micro-resources-all.js.map +1 -0
- package/dist/materials/micro-resources-component.d.ts +29 -0
- package/dist/materials/micro-resources-component.js +1 -0
- package/dist/materials/micro-resources-component.js.map +1 -0
- package/dist/materials/micro-resources-consumable.d.ts +29 -0
- package/dist/materials/micro-resources-consumable.js +1 -0
- package/dist/materials/micro-resources-consumable.js.map +1 -0
- package/dist/materials/micro-resources-data.d.ts +29 -0
- package/dist/materials/micro-resources-data.js +1 -0
- package/dist/materials/micro-resources-data.js.map +1 -0
- package/dist/materials/micro-resources-item.d.ts +29 -0
- package/dist/materials/micro-resources-item.js +1 -0
- package/dist/materials/micro-resources-item.js.map +1 -0
- package/dist/materials/micro-resources.d.ts +136 -0
- package/dist/materials/micro-resources.js +1 -0
- package/dist/materials/micro-resources.js.map +1 -0
- package/dist/ship-loadout-Ba63RDf-.d.ts +1059 -0
- package/dist/ships/ammunition.d.ts +107 -0
- package/dist/ships/ammunition.js +1 -0
- package/dist/ships/ammunition.js.map +1 -0
- package/dist/ships/armour.d.ts +134 -0
- package/dist/ships/armour.js +1 -0
- package/dist/ships/armour.js.map +1 -0
- package/dist/ships/blueprint-costs.d.ts +128 -0
- package/dist/ships/blueprint-costs.js +1 -0
- package/dist/ships/blueprint-costs.js.map +1 -0
- package/dist/ships/blueprint-journal.d.ts +116 -0
- package/dist/ships/blueprint-journal.js +1 -0
- package/dist/ships/blueprint-journal.js.map +1 -0
- package/dist/ships/blueprints.d.ts +103 -0
- package/dist/ships/blueprints.js +1 -0
- package/dist/ships/blueprints.js.map +1 -0
- package/dist/ships/decorative-modifications.d.ts +176 -0
- package/dist/ships/decorative-modifications.js +1 -0
- package/dist/ships/decorative-modifications.js.map +1 -0
- package/dist/ships/engineering-options.d.ts +246 -0
- package/dist/ships/engineering-options.js +1 -0
- package/dist/ships/engineering-options.js.map +1 -0
- package/dist/ships/engineering.d.ts +229 -0
- package/dist/ships/engineering.js +1 -0
- package/dist/ships/engineering.js.map +1 -0
- package/dist/ships/experimental-effect-costs.d.ts +56 -0
- package/dist/ships/experimental-effect-costs.js +1 -0
- package/dist/ships/experimental-effect-costs.js.map +1 -0
- package/dist/ships/experimental-effects.d.ts +62 -0
- package/dist/ships/experimental-effects.js +1 -0
- package/dist/ships/experimental-effects.js.map +1 -0
- package/dist/ships/index.d.ts +205 -0
- package/dist/ships/index.js +1 -0
- package/dist/ships/index.js.map +1 -0
- package/dist/ships/jump-range.d.ts +115 -0
- package/dist/ships/jump-range.js +1 -0
- package/dist/ships/jump-range.js.map +1 -0
- package/dist/ships/loadout-calculations.d.ts +109 -0
- package/dist/ships/loadout-calculations.js +1 -0
- package/dist/ships/loadout-calculations.js.map +1 -0
- package/dist/ships/loadout-validation.d.ts +80 -0
- package/dist/ships/loadout-validation.js +1 -0
- package/dist/ships/loadout-validation.js.map +1 -0
- package/dist/ships/module-capabilities.d.ts +205 -0
- package/dist/ships/module-capabilities.js +1 -0
- package/dist/ships/module-capabilities.js.map +1 -0
- package/dist/ships/modules-all.d.ts +43 -0
- package/dist/ships/modules-all.js +1 -0
- package/dist/ships/modules-all.js.map +1 -0
- package/dist/ships/modules-core.d.ts +40 -0
- package/dist/ships/modules-core.js +1 -0
- package/dist/ships/modules-core.js.map +1 -0
- package/dist/ships/modules-hardpoint.d.ts +42 -0
- package/dist/ships/modules-hardpoint.js +1 -0
- package/dist/ships/modules-hardpoint.js.map +1 -0
- package/dist/ships/modules-internal.d.ts +40 -0
- package/dist/ships/modules-internal.js +1 -0
- package/dist/ships/modules-internal.js.map +1 -0
- package/dist/ships/modules-utility.d.ts +40 -0
- package/dist/ships/modules-utility.js +1 -0
- package/dist/ships/modules-utility.js.map +1 -0
- package/dist/ships/modules.d.ts +755 -0
- package/dist/ships/modules.js +1 -0
- package/dist/ships/modules.js.map +1 -0
- package/dist/ships/power.d.ts +168 -0
- package/dist/ships/power.js +1 -0
- package/dist/ships/power.js.map +1 -0
- package/dist/ships/pre-engineered-stats.d.ts +147 -0
- package/dist/ships/pre-engineered-stats.js +1 -0
- package/dist/ships/pre-engineered-stats.js.map +1 -0
- package/dist/ships/pre-engineered.d.ts +215 -0
- package/dist/ships/pre-engineered.js +1 -0
- package/dist/ships/pre-engineered.js.map +1 -0
- package/dist/ships/resistances.d.ts +208 -0
- package/dist/ships/resistances.js +1 -0
- package/dist/ships/resistances.js.map +1 -0
- package/dist/ships/shields.d.ts +221 -0
- package/dist/ships/shields.js +1 -0
- package/dist/ships/shields.js.map +1 -0
- package/dist/ships/ship-loadout.d.ts +16 -0
- package/dist/ships/ship-loadout.js +1 -0
- package/dist/ships/ship-loadout.js.map +1 -0
- package/dist/ships/ships.d.ts +191 -0
- package/dist/ships/ships.js +1 -0
- package/dist/ships/ships.js.map +1 -0
- package/dist/ships/slef.d.ts +318 -0
- package/dist/ships/slef.js +1 -0
- package/dist/ships/slef.js.map +1 -0
- package/dist/ships/slots.d.ts +418 -0
- package/dist/ships/slots.js +1 -0
- package/dist/ships/slots.js.map +1 -0
- package/dist/ships/source-purchase.d.ts +132 -0
- package/dist/ships/source-purchase.js +1 -0
- package/dist/ships/source-purchase.js.map +1 -0
- package/dist/ships/weapons.d.ts +380 -0
- package/dist/ships/weapons.js +1 -0
- package/dist/ships/weapons.js.map +1 -0
- package/dist/system-address-DYsN1qOT.d.ts +313 -0
- package/package.json +375 -0
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
import { EngineeringGroupId } from './engineering-options.js';
|
|
2
|
+
import { ModuleSlot, SlotRestriction } from './slots.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Outfitting-module types and lookups.
|
|
6
|
+
*
|
|
7
|
+
* Elite Dangerous has ~1200 fittable modules. This module holds the
|
|
8
|
+
* {@link OutfittingModule} record shape — a module's **identity and its stats**
|
|
9
|
+
* together — and the functions that find one ({@link getModuleBySymbol},
|
|
10
|
+
* {@link getModulesByName}, {@link getBulkheadsForShip}).
|
|
11
|
+
*
|
|
12
|
+
* **Every lookup searches all 1199 modules by default.** A journal `Item` string does
|
|
13
|
+
* not identify its outfitting category, so callers need no category for lookup:
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* getModuleBySymbol('Hpt_PulseLaser_Fixed_Small')?.name; // -> 'Pulse Laser'
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Each lookup takes an optional second argument to **narrow** the search to a
|
|
20
|
+
* subset — any array you have filtered yourself. The catalogue is also exported split
|
|
21
|
+
* by Frontier's four outfitting categories:
|
|
22
|
+
*
|
|
23
|
+
* | Module | Export | Entries |
|
|
24
|
+
* | --- | --- | --- |
|
|
25
|
+
* | `./modules-core` | `CORE_MODULES` | 521 |
|
|
26
|
+
* | `./modules-internal` | `INTERNAL_MODULES` | 484 |
|
|
27
|
+
* | `./modules-hardpoint` | `HARDPOINT_MODULES` | 159 |
|
|
28
|
+
* | `./modules-utility` | `UTILITY_MODULES` | 35 |
|
|
29
|
+
* | `./modules-all` | `ALL_MODULES` | 1199 (the default) |
|
|
30
|
+
*
|
|
31
|
+
* Those four are for **listing** a category — an outfitting screen's hardpoint tab.
|
|
32
|
+
* They make poor narrowing arguments: no module symbol or display name is shared
|
|
33
|
+
* across categories, so passing one to a lookup can only make it miss.
|
|
34
|
+
*
|
|
35
|
+
* The record shape is intentionally sparse. Use the data-free guards in
|
|
36
|
+
* `./module-capabilities` to narrow a lookup result before reading a complete stat group:
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* const module = getModuleBySymbol(journalItem);
|
|
40
|
+
* if (hasFrameShiftDriveJumpStats(module)) module.maxFuel; // required here, in tonnes
|
|
41
|
+
* if (hasWeaponDamageStats(module)) weaponMetrics(module);
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* **This is the one default that costs real bundle weight.** A lookup imported from
|
|
46
|
+
* here pulls all four catalogues — 311.9 KiB minified (30.5 KiB gzipped) — since
|
|
47
|
+
* that is what it falls back to, and passing an explicit catalogue does not undo it.
|
|
48
|
+
* A build that must carry only one category should import that catalogue and search
|
|
49
|
+
* it directly:
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* // Catalogue symbols are mixed-case; a journal's are not.
|
|
53
|
+
* UTILITY_MODULES.find((m) => m.symbol.toLowerCase() === wanted);
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
|
|
59
|
+
*
|
|
60
|
+
* getModuleBySymbol('hpt_pulselaser_fixed_small')?.name; // -> 'Pulse Laser'
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @packageDocumentation
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Frontier's outfitting category — which kind of slot a module fits.
|
|
68
|
+
*
|
|
69
|
+
* - `core` — the core internals every hull must fit (armour, power plant, thrusters,
|
|
70
|
+
* frame shift drive, life support, power distributor, sensors, fuel tank). Frontier's
|
|
71
|
+
* own registry calls this category "standard"; it is named for the slots it fills,
|
|
72
|
+
* which are the same seven {@link CoreSlotType}s plus armour. A fuel tank is a `core`
|
|
73
|
+
* module that also fits an optional slot.
|
|
74
|
+
* - `internal` — optional internals (cargo racks, shield generators, fuel scoops,
|
|
75
|
+
* passenger cabins, limpet and planetary controllers, …).
|
|
76
|
+
* - `hardpoint` — the weapons and tools mounted on a hardpoint.
|
|
77
|
+
* - `utility` — the small utility-mount fittings (chaff, heat sinks, point defence,
|
|
78
|
+
* shield boosters, scanners).
|
|
79
|
+
*/
|
|
80
|
+
type ModuleCategory = 'core' | 'internal' | 'hardpoint' | 'utility';
|
|
81
|
+
/** How a hardpoint weapon is aimed. Only hardpoint modules carry a mount. */
|
|
82
|
+
type ModuleMount = 'Fixed' | 'Gimballed' | 'Turreted';
|
|
83
|
+
/** A missile/torpedo hardpoint's guidance. Only some hardpoints carry one. */
|
|
84
|
+
type ModuleGuidance = 'Dumbfire' | 'Seeker' | 'Swarm';
|
|
85
|
+
/** A module's grade letter, best (`A`) to worst; `I` is the armour placeholder. */
|
|
86
|
+
type ModuleRating = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I';
|
|
87
|
+
/**
|
|
88
|
+
* How a weapon's damage splits across the damage types, as fractions of one shot.
|
|
89
|
+
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* The conventional shares — {@link DamageDistribution.kinetic | kinetic},
|
|
92
|
+
* {@link DamageDistribution.thermal | thermal},
|
|
93
|
+
* {@link DamageDistribution.explosive | explosive},
|
|
94
|
+
* {@link DamageDistribution.absolute | absolute}, and any
|
|
95
|
+
* {@link DamageDistribution.unclassified | unclassified} share — partition the damage and sum to
|
|
96
|
+
* `1`; a type a weapon does not deal is absent rather than `0`. Kinetic, thermal and
|
|
97
|
+
* explosive damage meet the defender's resistance of the same name. No shield or hull
|
|
98
|
+
* resistance reduces absolute damage; the type and mitigation of unclassified damage
|
|
99
|
+
* are not established by in-game verification.
|
|
100
|
+
*
|
|
101
|
+
* {@link DamageDistribution.antiXeno | antiXeno} is different: it **overlays** the
|
|
102
|
+
* conventional split instead of partitioning it, flagging the portion that is effective
|
|
103
|
+
* against Thargoid targets. It is expressed relative to conventional damage and can
|
|
104
|
+
* exceed `1`, so a distribution's values can sum past `1`.
|
|
105
|
+
*/
|
|
106
|
+
interface DamageDistribution {
|
|
107
|
+
/** Kinetic share of one shot's damage, `0`–`1`. */
|
|
108
|
+
readonly kinetic?: number;
|
|
109
|
+
/** Thermal share of one shot's damage, `0`–`1`. */
|
|
110
|
+
readonly thermal?: number;
|
|
111
|
+
/** Explosive share of one shot's damage, `0`–`1`. */
|
|
112
|
+
readonly explosive?: number;
|
|
113
|
+
/** Absolute share — damage no resistance reduces — of one shot's damage, `0`–`1`. */
|
|
114
|
+
readonly absolute?: number;
|
|
115
|
+
/** Share unclassified by in-game verification, `0`–`1`. */
|
|
116
|
+
readonly unclassified?: number;
|
|
117
|
+
/**
|
|
118
|
+
* Anti-xeno ratio: the amount effective against Thargoids divided by conventional
|
|
119
|
+
* damage. Non-negative and potentially greater than `1`; see the type's remarks.
|
|
120
|
+
*/
|
|
121
|
+
readonly antiXeno?: number;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Exact damage amounts carried by one round, or one second of continuous fire.
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* Every amount is non-negative. Kinetic, thermal, explosive, absolute and all
|
|
128
|
+
* `unclassified` entries sum to the module's conventional {@link OutfittingModule.damage}.
|
|
129
|
+
* `antiXeno` overlays that conventional amount and is not added to it. The exact amounts
|
|
130
|
+
* are authoritative when present; {@link DamageDistribution} remains the compatible
|
|
131
|
+
* fractional projection.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* import type { DamageComponents } from '@elite-dangerous-almanac/core/ships/modules';
|
|
136
|
+
*
|
|
137
|
+
* const components: DamageComponents = { explosive: 27, antiXeno: 43 };
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
interface DamageComponents {
|
|
141
|
+
/** Non-negative kinetic damage. */
|
|
142
|
+
readonly kinetic?: number;
|
|
143
|
+
/** Non-negative thermal damage. */
|
|
144
|
+
readonly thermal?: number;
|
|
145
|
+
/** Non-negative explosive damage. */
|
|
146
|
+
readonly explosive?: number;
|
|
147
|
+
/** Non-negative absolute damage, which no resistance reduces. */
|
|
148
|
+
readonly absolute?: number;
|
|
149
|
+
/** Non-negative damage effective against Thargoid targets, overlaid on conventional damage. */
|
|
150
|
+
readonly antiXeno?: number;
|
|
151
|
+
/** Non-negative damage amounts unclassified by in-game verification. */
|
|
152
|
+
readonly unclassified?: readonly number[];
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* In-game projectile boundary parameters that are not effective weapon ranges.
|
|
156
|
+
*
|
|
157
|
+
* @remarks
|
|
158
|
+
* Values are non-negative boundary parameters. They are deliberately not stated in
|
|
159
|
+
* metres and must not be passed to a range attenuation calculation: projectile reach
|
|
160
|
+
* depends on projectile behavior not represented by these two numbers.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* import type { ProjectileRangeBoundaries } from '@elite-dangerous-almanac/core/ships/modules';
|
|
165
|
+
*
|
|
166
|
+
* const boundaries: ProjectileRangeBoundaries = {
|
|
167
|
+
* maximumBoundary: 0,
|
|
168
|
+
* falloffBoundary: 100000,
|
|
169
|
+
* };
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
interface ProjectileRangeBoundaries {
|
|
173
|
+
/** Non-negative maximum boundary parameter observed in-game, when present. */
|
|
174
|
+
readonly maximumBoundary?: number;
|
|
175
|
+
/** Non-negative falloff boundary parameter observed in-game. */
|
|
176
|
+
readonly falloffBoundary: number;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Identity, classification, fit constraints, and price for one outfitting module.
|
|
180
|
+
*
|
|
181
|
+
* @remarks
|
|
182
|
+
* The core identity fields (`symbol`, `name`, `category`, `class`, and `rating`) are
|
|
183
|
+
* always present. Optional fields describe fit restrictions, purchase entitlement, and
|
|
184
|
+
* price. Performance data belongs to {@link OutfittingModuleStats}; the complete flat
|
|
185
|
+
* catalogue record is {@link OutfittingModule}.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* import type { OutfittingModuleIdentity } from '@elite-dangerous-almanac/core/ships/modules';
|
|
190
|
+
*
|
|
191
|
+
* const identity: OutfittingModuleIdentity = {
|
|
192
|
+
* symbol: 'CustomCargoRack',
|
|
193
|
+
* category: 'internal',
|
|
194
|
+
* engineeringGroup: 'cargoRacks',
|
|
195
|
+
* name: 'Custom Cargo Rack',
|
|
196
|
+
* class: 2,
|
|
197
|
+
* rating: 'E',
|
|
198
|
+
* };
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
interface OutfittingModuleIdentity {
|
|
202
|
+
/** Internal identifier, e.g. `"Hpt_PulseLaser_Fixed_Small"`. Unique — the module's key. */
|
|
203
|
+
readonly symbol: string;
|
|
204
|
+
/**
|
|
205
|
+
* Which kind of slot the module fits.
|
|
206
|
+
*
|
|
207
|
+
* @remarks
|
|
208
|
+
* Derived from the catalogue the record was read from rather than stored on it —
|
|
209
|
+
* `CORE_MODULES` is what makes a record `'core'` — so it is always present and
|
|
210
|
+
* always agrees with the catalogue you found the module in — it is written after
|
|
211
|
+
* the record's own fields, so the file wins outright. That also makes it the last
|
|
212
|
+
* key on the record, which is worth knowing only if you serialize one and compare
|
|
213
|
+
* the resulting string.
|
|
214
|
+
*/
|
|
215
|
+
readonly category: ModuleCategory;
|
|
216
|
+
/**
|
|
217
|
+
* Stable engineering-menu family, or `null` when no source classifies this module.
|
|
218
|
+
* See {@link EngineeringGroupId}.
|
|
219
|
+
*/
|
|
220
|
+
readonly engineeringGroup: EngineeringGroupId | null;
|
|
221
|
+
/**
|
|
222
|
+
* The one fixed mount this module fills, when it fills one: `'armour'` or one of
|
|
223
|
+
* the seven {@link CoreSlotType} core functions.
|
|
224
|
+
*
|
|
225
|
+
* @remarks
|
|
226
|
+
* Present on every `core` module, and on the fifteen Guardian Hybrid power plants
|
|
227
|
+
* and power distributors — which Frontier files under `internal`, but which go in
|
|
228
|
+
* a core mount. Absent on everything else, because there is no one mount to name:
|
|
229
|
+
* a weapon, a utility fitting or an ordinary optional internal fits any mount of
|
|
230
|
+
* its kind that is large enough.
|
|
231
|
+
*
|
|
232
|
+
* This is the module's half of the fit rule and `BuildSlot.core` is the mount's
|
|
233
|
+
* half; `ShipLoadout.setModule` matches the two. Read it rather than inferring a
|
|
234
|
+
* mount from the symbol — `Int_Engine_*` being thrusters is a naming habit, not a
|
|
235
|
+
* guarantee, and the Python Mk II's `Int_MkIIAgileBoost_*` thrusters already break
|
|
236
|
+
* it.
|
|
237
|
+
*
|
|
238
|
+
* A `fuelTank` is the one module that fits somewhere else as well: its own core
|
|
239
|
+
* mount *and* any optional slot large enough.
|
|
240
|
+
*
|
|
241
|
+
* **The rule is read off the record, not off the symbol** — the same way
|
|
242
|
+
* {@link OutfittingModule.restrictedToShips} behaves, and with the same
|
|
243
|
+
* consequence: a record you assemble yourself from a journal `Item` string, with
|
|
244
|
+
* no `slot` on it, will not go into a core mount. Resolve records from a catalogue
|
|
245
|
+
* ({@link getModuleBySymbol}) and the question does not arise.
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```ts
|
|
249
|
+
* import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
|
|
250
|
+
*
|
|
251
|
+
* getModuleBySymbol('Int_Hyperdrive_Size5_Class5')?.slot; // -> 'frameShiftDrive'
|
|
252
|
+
* getModuleBySymbol('Anaconda_Armour_Grade1')?.slot; // -> 'armour'
|
|
253
|
+
* getModuleBySymbol('Int_CargoRack_Size4_Class1')?.slot; // -> undefined
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
readonly slot?: ModuleSlot;
|
|
257
|
+
/**
|
|
258
|
+
* Stable, descriptive English name, e.g. `"Pulse Laser"`.
|
|
259
|
+
*
|
|
260
|
+
* @remarks
|
|
261
|
+
* This is a canonical library label, not a byte-exact copy of the game's
|
|
262
|
+
* localized UI text: abbreviations such as FSD and AFM are expanded for readability.
|
|
263
|
+
* It is not localized and is not suitable as a localization key.
|
|
264
|
+
*
|
|
265
|
+
* **Not unique** — the game shows most modules at several sizes and ratings, and
|
|
266
|
+
* every hull's armour shares the same five names. Use {@link OutfittingModule.symbol}
|
|
267
|
+
* as the key; {@link getModulesByName} returns every match.
|
|
268
|
+
*/
|
|
269
|
+
readonly name: string;
|
|
270
|
+
/**
|
|
271
|
+
* The module size, `0`–`8` — the number in the "5A" the outfitting screen shows.
|
|
272
|
+
*
|
|
273
|
+
* @remarks
|
|
274
|
+
* Frontier calls this the module *class*; it is the slot-size number, not the
|
|
275
|
+
* grade letter (that is {@link OutfittingModule.rating}). Named `class` to match
|
|
276
|
+
* the source registry.
|
|
277
|
+
*/
|
|
278
|
+
readonly class: number;
|
|
279
|
+
/** The grade letter, `A`–`I` — the letter in the "5A" the screen shows. */
|
|
280
|
+
readonly rating: ModuleRating;
|
|
281
|
+
/**
|
|
282
|
+
* How the weapon is aimed. Present only on hardpoint weapons that have a mount
|
|
283
|
+
* variant; absent on every other module.
|
|
284
|
+
*/
|
|
285
|
+
readonly mount?: ModuleMount;
|
|
286
|
+
/**
|
|
287
|
+
* A missile/torpedo hardpoint's guidance. Present only on the launchers that
|
|
288
|
+
* have one; absent on everything else.
|
|
289
|
+
*/
|
|
290
|
+
readonly guidance?: ModuleGuidance;
|
|
291
|
+
/**
|
|
292
|
+
* The hull an armour variant belongs to, e.g. `"Anaconda"`. Present only on the
|
|
293
|
+
* `core`-category armour modules, which are the one ship-specific module;
|
|
294
|
+
* absent on every generic module.
|
|
295
|
+
*/
|
|
296
|
+
readonly ship?: string;
|
|
297
|
+
/**
|
|
298
|
+
* Frontier's DLC / purchase-grant entitlement token, e.g.
|
|
299
|
+
* `"ELITE_HORIZONS_V_PLANETARY_LANDINGS"`. Present only on gated modules.
|
|
300
|
+
*/
|
|
301
|
+
readonly entitlement?: string;
|
|
302
|
+
/**
|
|
303
|
+
* The hull symbol(s) a module is restricted to, when it is ship-specific — e.g.
|
|
304
|
+
* `["Explorer_NX"]` for the Python Mk II's MkII Gravity Optimised thrusters.
|
|
305
|
+
*
|
|
306
|
+
* @remarks
|
|
307
|
+
* Present only on the handful of non-armour modules limited to particular hulls.
|
|
308
|
+
* Armour is ship-specific too, but that restriction lives in
|
|
309
|
+
* {@link OutfittingModule.ship} / {@link getBulkheadsForShip}, not here. Symbols
|
|
310
|
+
* match {@link Ship.symbol}.
|
|
311
|
+
*/
|
|
312
|
+
readonly restrictedToShips?: readonly string[];
|
|
313
|
+
/**
|
|
314
|
+
* The slot restriction a module **requires** — it fits only mounts carrying this
|
|
315
|
+
* {@link SlotRestriction}, and no unrestricted mount at all.
|
|
316
|
+
*
|
|
317
|
+
* @remarks
|
|
318
|
+
* Not to be confused with {@link OutfittingModule.slot}, which names *one* mount
|
|
319
|
+
* the module fills; this narrows a whole family of them, and the two never appear
|
|
320
|
+
* on the same record.
|
|
321
|
+
*
|
|
322
|
+
* The mirror image of `BuildSlot.restriction`, and the other half of the same
|
|
323
|
+
* rule: a mount's restriction says which modules it takes, this says which mounts
|
|
324
|
+
* a module goes in. Most restricted families bind one way only — a cargo rack fits
|
|
325
|
+
* a `cargo` mount *and* any unrestricted optional — so this is present on just the
|
|
326
|
+
* five records the game sells for one kind of mount and nowhere else:
|
|
327
|
+
*
|
|
328
|
+
* | Module | Requires |
|
|
329
|
+
* | --- | --- |
|
|
330
|
+
* | `Int_PlanetApproachSuite`, `Int_PlanetApproachSuite_Advanced` | `planetaryApproachSuite` |
|
|
331
|
+
* | `Int_LargeCargoRack_Size7_Class1`, `Int_LargeCargoRack_Size8_class1` (Mk II Cargo Rack) | `cargo` |
|
|
332
|
+
* | `Int_MultiDroneControl_MiningV2_Size5_Class5` (Mk II Mining Multi-Limpet Controller) | `limpetController` |
|
|
333
|
+
*
|
|
334
|
+
* It composes with {@link OutfittingModule.restrictedToShips} rather than
|
|
335
|
+
* replacing it: the Mk II racks name both the hull that can buy them and the kind
|
|
336
|
+
* of mount they go in, and a build must satisfy both. Where a module names a hull
|
|
337
|
+
* and nothing else — the Mk II Vessel Hangars, say — it fits that hull's ordinary
|
|
338
|
+
* optionals like anything else.
|
|
339
|
+
*
|
|
340
|
+
* **The rule is read off the record, not off the symbol.** A module you assemble
|
|
341
|
+
* yourself — from a journal `Item` string, say — is refused only if you give it
|
|
342
|
+
* this field, exactly as `restrictedToShips` behaves. Resolve records from a
|
|
343
|
+
* catalogue and the question does not arise.
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
|
|
347
|
+
* import { INTERNAL_MODULES } from '@elite-dangerous-almanac/core/ships/modules-internal';
|
|
348
|
+
* import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';
|
|
349
|
+
*
|
|
350
|
+
* const rack = getModuleBySymbol('Int_LargeCargoRack_Size8_class1', INTERNAL_MODULES)!;
|
|
351
|
+
* rack.restrictedToSlot; // -> 'cargo'
|
|
352
|
+
* ShipLoadout.empty('PantherMkII').setModule('Cargo01', rack); // fits
|
|
353
|
+
* try {
|
|
354
|
+
* ShipLoadout.empty('PantherMkII').setModule('Slot01_Size8', rack);
|
|
355
|
+
* } catch (error) {
|
|
356
|
+
* if (error instanceof TypeError) error.message;
|
|
357
|
+
* // -> 'ShipLoadout.setModule: Int_LargeCargoRack_Size8_class1 → Slot01_Size8: module only fits a mount that takes cargo racks and fuel tanks'
|
|
358
|
+
* }
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
readonly restrictedToSlot?: SlotRestriction;
|
|
362
|
+
/**
|
|
363
|
+
* Standard purchase price, in credits — the base list price before any station
|
|
364
|
+
* discount or markup, which is what an outfitting screen quotes at 0% discount.
|
|
365
|
+
*
|
|
366
|
+
* @remarks
|
|
367
|
+
* Absent on the handful of records no registry prices: the starter `*_free`
|
|
368
|
+
* variants, the size-8 frame shift drives, and a few internals no outfitting
|
|
369
|
+
* registry carries a figure for — among them the two Corrosion Resistant Cargo
|
|
370
|
+
* Racks no station sells, which are not free. Treat `undefined` as "unknown", never
|
|
371
|
+
* as free — see [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
|
|
372
|
+
*/
|
|
373
|
+
readonly cost?: number;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Sparse performance and capability fields carried by an outfitting module.
|
|
377
|
+
*
|
|
378
|
+
* @remarks
|
|
379
|
+
* Every field is optional because no module family uses every stat. Use the guards in
|
|
380
|
+
* `./module-capabilities` when a calculation needs a complete group. The interface is
|
|
381
|
+
* also useful for functions that accept or return engineered stat snapshots without
|
|
382
|
+
* requiring a module's identity fields. Masses are tonnes, power is megawatts, jump
|
|
383
|
+
* ranges are light-years, and weapon ranges are metres.
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```ts
|
|
387
|
+
* import type { OutfittingModuleStats } from '@elite-dangerous-almanac/core/ships/modules';
|
|
388
|
+
*
|
|
389
|
+
* const engineered: OutfittingModuleStats = { mass: 18.4, powerDraw: 0.69 };
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
interface OutfittingModuleStats {
|
|
393
|
+
/** Mass, in tonnes. */
|
|
394
|
+
readonly mass?: number;
|
|
395
|
+
/** Integrity (hit points against module damage). */
|
|
396
|
+
readonly integrity?: number;
|
|
397
|
+
/** Power draw, in megawatts. */
|
|
398
|
+
readonly powerDraw?: number;
|
|
399
|
+
/** Boot time from power-on, in seconds. */
|
|
400
|
+
readonly bootTime?: number;
|
|
401
|
+
/** Optimised mass, in tonnes — thrusters, shield generators, and FSDs. */
|
|
402
|
+
readonly optMass?: number;
|
|
403
|
+
/** Minimum mass for the performance curve, in tonnes. */
|
|
404
|
+
readonly minMass?: number;
|
|
405
|
+
/** Maximum mass for the performance curve, in tonnes. */
|
|
406
|
+
readonly maxMass?: number;
|
|
407
|
+
/** Performance multiplier at `optMass` — thruster speed or shield strength. */
|
|
408
|
+
readonly optMultiplier?: number;
|
|
409
|
+
/** Minimum performance multiplier, reached at `maxMass`. */
|
|
410
|
+
readonly minMultiplier?: number;
|
|
411
|
+
/** Maximum performance multiplier, reached at `minMass`. */
|
|
412
|
+
readonly maxMultiplier?: number;
|
|
413
|
+
/**
|
|
414
|
+
* Thrusters: waste heat generated per second at top speed.
|
|
415
|
+
*
|
|
416
|
+
* @remarks
|
|
417
|
+
* The stat the journal calls `EngineHeatRate` — every Dirty Drive Tuning roll
|
|
418
|
+
* raises it and every Clean Drive roll lowers it. Frontier's own units: a bare
|
|
419
|
+
* number the ship's heat model consumes, not a temperature or a percentage.
|
|
420
|
+
*/
|
|
421
|
+
readonly engineHeatRate?: number;
|
|
422
|
+
/** FSD: maximum fuel per jump, in tonnes. */
|
|
423
|
+
readonly maxFuel?: number;
|
|
424
|
+
/** FSD: rating (linear) fuel constant. */
|
|
425
|
+
readonly fuelMul?: number;
|
|
426
|
+
/** FSD: size (power) fuel constant. */
|
|
427
|
+
readonly fuelPower?: number;
|
|
428
|
+
/**
|
|
429
|
+
* Frame shift drive: waste heat generated per second while charging a jump.
|
|
430
|
+
*
|
|
431
|
+
* @remarks
|
|
432
|
+
* The journal's `FSDHeatRate`, in the same units as
|
|
433
|
+
* {@link OutfittingModule.engineHeatRate}. It is what Faster Boot Sequence trades
|
|
434
|
+
* away, what Shielded improves, and the whole of the Deep Charge / Thermal Spread
|
|
435
|
+
* (`special_fsd_cooled`) experimental effect. A drive's size sets it — every rating
|
|
436
|
+
* of a size shares one value, and a supercruise-assist (SCO) drive matches the plain
|
|
437
|
+
* drive of the same size.
|
|
438
|
+
*/
|
|
439
|
+
readonly fsdHeatRate?: number;
|
|
440
|
+
/** Guardian FSD Booster: flat jump-range bonus, in light-years. */
|
|
441
|
+
readonly jumpBoost?: number;
|
|
442
|
+
/** Power plant: power generated, in megawatts. */
|
|
443
|
+
readonly powerCapacity?: number;
|
|
444
|
+
/** Power plant: heat efficiency (lower runs cooler). */
|
|
445
|
+
readonly heatEfficiency?: number;
|
|
446
|
+
/** Power distributor: WEP capacitor capacity. */
|
|
447
|
+
readonly weaponsCapacity?: number;
|
|
448
|
+
/** Power distributor: WEP recharge rate, per second. */
|
|
449
|
+
readonly weaponsRecharge?: number;
|
|
450
|
+
/** Power distributor: ENG capacitor capacity. */
|
|
451
|
+
readonly enginesCapacity?: number;
|
|
452
|
+
/** Power distributor: ENG recharge rate, per second. */
|
|
453
|
+
readonly enginesRecharge?: number;
|
|
454
|
+
/** Power distributor: SYS capacitor capacity. */
|
|
455
|
+
readonly systemsCapacity?: number;
|
|
456
|
+
/** Power distributor: SYS recharge rate, per second. */
|
|
457
|
+
readonly systemsRecharge?: number;
|
|
458
|
+
/** Fuel scoop: scoop rate, in tonnes per second. */
|
|
459
|
+
readonly refuelRate?: number;
|
|
460
|
+
/** Fuel tank: capacity, in tonnes. */
|
|
461
|
+
readonly fuelCapacity?: number;
|
|
462
|
+
/** Cargo rack: capacity, in tonnes. */
|
|
463
|
+
readonly cargoCapacity?: number;
|
|
464
|
+
/** Shield generator: regeneration rate, MJ per second. */
|
|
465
|
+
readonly shieldRegenRate?: number;
|
|
466
|
+
/** Shield generator: broken (down) regeneration rate, MJ per second. */
|
|
467
|
+
readonly shieldBrokenRegenRate?: number;
|
|
468
|
+
/** Shield booster: shield strength bonus, as a fraction (`0.04` = +4%). */
|
|
469
|
+
readonly shieldBoost?: number;
|
|
470
|
+
/** Shield cell bank: shield megajoules restored per second while a cell runs. */
|
|
471
|
+
readonly shieldBankReinforcement?: number;
|
|
472
|
+
/** Shield cell bank: waste heat generated by firing one cell. */
|
|
473
|
+
readonly shieldBankHeat?: number;
|
|
474
|
+
/** Shield cell bank: seconds between firing a cell and the shields starting to rise. */
|
|
475
|
+
readonly shieldBankSpinUp?: number;
|
|
476
|
+
/** Shield cell bank: seconds one cell keeps reinforcing for. */
|
|
477
|
+
readonly shieldBankDuration?: number;
|
|
478
|
+
/** Kinetic resistance, as a fraction (`0.4` = 40% resisted, `-0.2` = 20% weaker). */
|
|
479
|
+
readonly kineticResistance?: number;
|
|
480
|
+
/** Thermal resistance, as a fraction (negative is a weakness). */
|
|
481
|
+
readonly thermalResistance?: number;
|
|
482
|
+
/** Explosive resistance, as a fraction (negative is a weakness). */
|
|
483
|
+
readonly explosiveResistance?: number;
|
|
484
|
+
/** Caustic resistance, as a fraction (negative is a weakness). */
|
|
485
|
+
readonly causticResistance?: number;
|
|
486
|
+
/**
|
|
487
|
+
* Whether Anti-Guardian Zone Resistance protects this Guardian module from a
|
|
488
|
+
* Thargoid anti-Guardian field.
|
|
489
|
+
*
|
|
490
|
+
* @remarks
|
|
491
|
+
* A sparse capability flag rather than a percentage: `true` means the protection is
|
|
492
|
+
* inherent or the grade-1 blueprint grants it, while absence means it is not granted.
|
|
493
|
+
* The two Guardian Nanite Torpedo Pylons carry it inherently; read engineered
|
|
494
|
+
* protection from a fitted module's {@link FittedModule.effectiveStats}.
|
|
495
|
+
*/
|
|
496
|
+
readonly guardianZoneResistance?: boolean;
|
|
497
|
+
/**
|
|
498
|
+
* Whether this particular resolved article accepts no further engineering.
|
|
499
|
+
*
|
|
500
|
+
* @remarks
|
|
501
|
+
* Stock module catalogues omit this field. `getPreEngineeredStats` sets it on final
|
|
502
|
+
* pre-engineered Guardian weapons so a fitted article exposes an empty engineering
|
|
503
|
+
* menu and rejects both blueprints and experimental effects.
|
|
504
|
+
*/
|
|
505
|
+
readonly engineeringLocked?: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Armour: the hull hit points this bulkhead adds, as a fraction of the hull's
|
|
508
|
+
* {@link Ship.baseArmour} on top of it — `0.8` (lightweight alloy) means
|
|
509
|
+
* `baseArmour × 1.8`, `2.5` means `baseArmour × 3.5`.
|
|
510
|
+
*
|
|
511
|
+
* @remarks
|
|
512
|
+
* Carried by the ship-specific armour modules, which are the `core`-category
|
|
513
|
+
* records with a {@link OutfittingModule.ship}. List a hull's five (or, on the
|
|
514
|
+
* Caspian Explorer, six) options with {@link getBulkheadsForShip}.
|
|
515
|
+
*/
|
|
516
|
+
readonly hullBoost?: number;
|
|
517
|
+
/** Hull reinforcement package: hull hit points added. */
|
|
518
|
+
readonly hullReinforcement?: number;
|
|
519
|
+
/** Guardian shield reinforcement package: shield megajoules added. */
|
|
520
|
+
readonly shieldAddition?: number;
|
|
521
|
+
/**
|
|
522
|
+
* Module reinforcement package: the fraction of module damage it absorbs
|
|
523
|
+
* (`0.3` = 30%). Protects the *modules*, not the hull.
|
|
524
|
+
*/
|
|
525
|
+
readonly moduleProtection?: number;
|
|
526
|
+
/**
|
|
527
|
+
* Scan range, in **metres**.
|
|
528
|
+
*
|
|
529
|
+
* @remarks
|
|
530
|
+
* On a **utility scanner** it is the distance the scan reaches. On a **core sensor
|
|
531
|
+
* suite** it is the range at which a contact with typical emissions resolves — the
|
|
532
|
+
* "typical sensor range" the outfitting panel shows in kilometres and the journal
|
|
533
|
+
* reports in metres, not the suite's absolute detection ceiling.
|
|
534
|
+
*
|
|
535
|
+
* This is the sole distance field on utility scanners and sensor suites. A journal
|
|
536
|
+
* may spell its modifier `ScannerRange` or `Range`; both labels resolve here. Weapon
|
|
537
|
+
* distance is the separate {@link OutfittingModule.maximumRange} field.
|
|
538
|
+
*/
|
|
539
|
+
readonly scannerRange?: number;
|
|
540
|
+
/**
|
|
541
|
+
* Scan cone half-angle, in degrees — how far off boresight a target can sit and
|
|
542
|
+
* still be scanned. Wide Angle raises it; Long Range and Lightweight narrow it.
|
|
543
|
+
*/
|
|
544
|
+
readonly scanAngle?: number;
|
|
545
|
+
/** Seconds a scan takes to complete. Utility scanners only. */
|
|
546
|
+
readonly scanTime?: number;
|
|
547
|
+
/**
|
|
548
|
+
* Detailed Surface Scanner: probe radius, as a **percentage** (`20` = the stock
|
|
549
|
+
* 20%).
|
|
550
|
+
*
|
|
551
|
+
* @remarks
|
|
552
|
+
* Frontier stores this one as a percentage rather than a fraction, and the journal
|
|
553
|
+
* reports it that way too — a grade 4 Expanded Probe Scanning Radius roll takes the
|
|
554
|
+
* stock `20` to `28`. The journal spells the label `DSS_PatchRadius`; the blueprint
|
|
555
|
+
* recipe spells it `ProbeRadius`, and both resolve here.
|
|
556
|
+
*/
|
|
557
|
+
readonly probeRadius?: number;
|
|
558
|
+
/** FSD interdictor: maximum target angle off boresight, in degrees. */
|
|
559
|
+
readonly interdictorFacingLimit?: number;
|
|
560
|
+
/**
|
|
561
|
+
* FSD interdictor: maximum target range, in **seconds to intercept** — the units the
|
|
562
|
+
* game measures a supercruise separation in, not a distance.
|
|
563
|
+
*/
|
|
564
|
+
readonly interdictorRange?: number;
|
|
565
|
+
/**
|
|
566
|
+
* `true` when a hardpoint-mounted module draws its power continuously.
|
|
567
|
+
*
|
|
568
|
+
* @remarks
|
|
569
|
+
* Weapons and most utility fittings only draw power while the hardpoints are
|
|
570
|
+
* deployed; shield boosters, chaff, heat sinks, point defence, caustic sinks and
|
|
571
|
+
* shutdown field neutralisers draw theirs all the time, and carry this flag.
|
|
572
|
+
* Absent on every `core`/`internal` module, which are always powered anyway.
|
|
573
|
+
* See {@link powerDraw} and `./power`.
|
|
574
|
+
*/
|
|
575
|
+
readonly alwaysPowered?: boolean;
|
|
576
|
+
/** Damage per round — or per second on a continuous-fire (beam) weapon. */
|
|
577
|
+
readonly damage?: number;
|
|
578
|
+
/** How `damage` splits across the damage types. */
|
|
579
|
+
readonly damageDistribution?: DamageDistribution;
|
|
580
|
+
/**
|
|
581
|
+
* Exact damage amounts when in-game verification exposes distinct components.
|
|
582
|
+
* On effective fitted stats these scale with engineered total damage, and are absent
|
|
583
|
+
* when engineering converts the weapon to a new fractional damage distribution.
|
|
584
|
+
*/
|
|
585
|
+
readonly damageComponents?: DamageComponents;
|
|
586
|
+
/**
|
|
587
|
+
* Rounds fired per shot, for the weapons that fire several at once (fragment
|
|
588
|
+
* cannons, shard cannons). Absent means one round per shot.
|
|
589
|
+
*/
|
|
590
|
+
readonly roundsPerShot?: number;
|
|
591
|
+
/**
|
|
592
|
+
* Shots per second with the burst pattern folded in — the journal's `RateOfFire`.
|
|
593
|
+
*
|
|
594
|
+
* @remarks
|
|
595
|
+
* Absent on continuous-fire weapons (beam and mining lasers), whose `damage` is
|
|
596
|
+
* already per second. Excludes charge and reload time; {@link OutfittingModule.chargeTime}
|
|
597
|
+
* is the delay before a shot lands, while {@link OutfittingModule.clipSize} and
|
|
598
|
+
* {@link OutfittingModule.reloadTime} give the sustained rate.
|
|
599
|
+
*/
|
|
600
|
+
readonly rateOfFire?: number;
|
|
601
|
+
/** Seconds between shots — between *bursts* on a burst-fire weapon. */
|
|
602
|
+
readonly burstInterval?: number;
|
|
603
|
+
/** Shots in one burst. Absent (or `1`) on a weapon that does not fire in bursts. */
|
|
604
|
+
readonly burstRounds?: number;
|
|
605
|
+
/** Shots per second *within* a burst. */
|
|
606
|
+
readonly burstRateOfFire?: number;
|
|
607
|
+
/** Seconds spent charging before a shot (rail guns), if any. */
|
|
608
|
+
readonly chargeTime?: number;
|
|
609
|
+
/**
|
|
610
|
+
* Rounds in a clip before reloading. Absent on weapons that never reload.
|
|
611
|
+
*
|
|
612
|
+
* @remarks
|
|
613
|
+
* A capacity, and the largest `AmmoInClip` a journal can report for the module.
|
|
614
|
+
* `ammunitionCapacity` in `./ammunition` reads it together with
|
|
615
|
+
* {@link OutfittingModule.ammoMaximum}.
|
|
616
|
+
*/
|
|
617
|
+
readonly clipSize?: number;
|
|
618
|
+
/**
|
|
619
|
+
* Reserve rounds to reload from — the magazine is *not* counted in it, exactly as the
|
|
620
|
+
* journal's `AmmoInHopper` does not count it. Absent beside a {@link clipSize} means
|
|
621
|
+
* nothing limits the refills (the mining Abrasion Blaster); absent beside no clip
|
|
622
|
+
* either means the module takes no ammunition at all, as the lasers do.
|
|
623
|
+
*/
|
|
624
|
+
readonly ammoMaximum?: number;
|
|
625
|
+
/** Seconds to reload a clip. */
|
|
626
|
+
readonly reloadTime?: number;
|
|
627
|
+
/**
|
|
628
|
+
* Weapons-capacitor draw, in megawatts — per shot, or per second on a
|
|
629
|
+
* continuous-fire weapon. Shield generators carry it too, as the systems-capacitor
|
|
630
|
+
* cost of one MJ per second of regeneration — the stat the journal calls
|
|
631
|
+
* `EnergyPerRegen` rather than `DistributorDraw`, and the one Hi-Cap, Lo-draw and
|
|
632
|
+
* Force Block move.
|
|
633
|
+
*/
|
|
634
|
+
readonly distributorDraw?: number;
|
|
635
|
+
/** Heat generated — per shot, or per second on a continuous-fire weapon. */
|
|
636
|
+
readonly thermalLoad?: number;
|
|
637
|
+
/**
|
|
638
|
+
* Armour piercing rating. Damage to a hull is scaled by
|
|
639
|
+
* `min(1, armourPiercing / hardness)` against a hull of that {@link Ship.hardness}.
|
|
640
|
+
*/
|
|
641
|
+
readonly armourPiercing?: number;
|
|
642
|
+
/**
|
|
643
|
+
* Maximum effective range, in metres. A weapon does no damage beyond it; on a
|
|
644
|
+
* non-scanner utility module, it is the effect's reach.
|
|
645
|
+
*/
|
|
646
|
+
readonly maximumRange?: number;
|
|
647
|
+
/** Range at which damage starts to drop off, in metres. */
|
|
648
|
+
readonly falloffRange?: number;
|
|
649
|
+
/** Projectile boundary parameters; these are not effective distances in metres. */
|
|
650
|
+
readonly projectileRange?: ProjectileRangeBoundaries;
|
|
651
|
+
/**
|
|
652
|
+
* Projectile speed, in metres per second.
|
|
653
|
+
*
|
|
654
|
+
* @remarks
|
|
655
|
+
* Absent on the weapons that have no projectile to speed up — the pulse, burst,
|
|
656
|
+
* beam and mining lasers, rail guns, Gauss cannons and mine launchers all hit (or
|
|
657
|
+
* drop) where they are aimed. No registry publishes a figure for them because there
|
|
658
|
+
* is none, so Long Range and Focused simply leave their shot speed alone; see
|
|
659
|
+
* {@link ShipLoadout.applyBlueprint}.
|
|
660
|
+
*/
|
|
661
|
+
readonly shotSpeed?: number;
|
|
662
|
+
/** Maximum aim deviation, in degrees. */
|
|
663
|
+
readonly jitter?: number;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* One fittable outfitting module: its identity and sparse stats in one flat record.
|
|
667
|
+
*
|
|
668
|
+
* @remarks
|
|
669
|
+
* Keeping the runtime record flat lets engineering modifiers address stat keys directly.
|
|
670
|
+
* Consumers that need a smaller contract can accept {@link OutfittingModuleIdentity},
|
|
671
|
+
* {@link OutfittingModuleStats}, or one of the required groups in
|
|
672
|
+
* `./module-capabilities`.
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* ```ts
|
|
676
|
+
* import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
|
|
677
|
+
*
|
|
678
|
+
* getModuleBySymbol('Int_Hyperdrive_Size5_Class5')?.engineeringGroup;
|
|
679
|
+
* // -> 'frameShiftDrives'
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
interface OutfittingModule extends OutfittingModuleIdentity, OutfittingModuleStats {
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Look up a module by its internal symbol, case-insensitively.
|
|
686
|
+
*
|
|
687
|
+
* @param symbol - The internal identifier, e.g. `"Hpt_PulseLaser_Fixed_Small"`.
|
|
688
|
+
* Leading/trailing whitespace and case are ignored, so the journal's lower-cased
|
|
689
|
+
* form resolves too.
|
|
690
|
+
* @param modules - Optional subset to search instead of all 1199 modules —
|
|
691
|
+
* `CORE_MODULES`, `INTERNAL_MODULES`, `HARDPOINT_MODULES`, `UTILITY_MODULES`, or any
|
|
692
|
+
* array you have filtered yourself. Omit it unless you specifically want to exclude
|
|
693
|
+
* the other categories; a symbol is unique across all four.
|
|
694
|
+
* @returns The matching {@link OutfittingModule}, or `null` if no module has that
|
|
695
|
+
* symbol.
|
|
696
|
+
* @throws {TypeError} If `symbol` is present and not a string. A nullish
|
|
697
|
+
* `symbol` is a miss, answered the way an unrecognised one is.
|
|
698
|
+
* @example
|
|
699
|
+
* ```ts
|
|
700
|
+
* import { getModuleBySymbol } from '@elite-dangerous-almanac/core/ships/modules';
|
|
701
|
+
*
|
|
702
|
+
* getModuleBySymbol('hpt_pulselaser_fixed_small')?.class; // -> 1
|
|
703
|
+
* ```
|
|
704
|
+
*/
|
|
705
|
+
declare function getModuleBySymbol(symbol: string, modules?: readonly OutfittingModule[]): OutfittingModule | null;
|
|
706
|
+
/**
|
|
707
|
+
* Every module with a given display name, in catalogue order.
|
|
708
|
+
*
|
|
709
|
+
* @param name - The display name as the registry spells it, e.g. `"Pulse Laser"`.
|
|
710
|
+
* Leading/trailing whitespace and case are ignored, but matching is otherwise exact.
|
|
711
|
+
* @param modules - Optional subset to search (see {@link getModuleBySymbol}).
|
|
712
|
+
* @returns All matching modules — the name is shared across sizes, ratings and (for
|
|
713
|
+
* armour) hulls, so this returns an array. Empty if none match. The input array is
|
|
714
|
+
* not modified.
|
|
715
|
+
* @throws {TypeError} If `name` is present and not a string. A nullish
|
|
716
|
+
* `name` is a miss, answered the way an unrecognised one is.
|
|
717
|
+
* @example
|
|
718
|
+
* ```ts
|
|
719
|
+
* import { getModulesByName } from '@elite-dangerous-almanac/core/ships/modules';
|
|
720
|
+
*
|
|
721
|
+
* getModulesByName('pulse laser').length; // -> every size/mount variant
|
|
722
|
+
* ```
|
|
723
|
+
*/
|
|
724
|
+
declare function getModulesByName(name: string, modules?: readonly OutfittingModule[]): OutfittingModule[];
|
|
725
|
+
/**
|
|
726
|
+
* Every bulkhead (armour) variant a given hull can be fitted with, in catalogue order.
|
|
727
|
+
*
|
|
728
|
+
* @param ship - The hull's display name as the registry spells it, e.g.
|
|
729
|
+
* `"Anaconda"`. Leading/trailing whitespace and case are ignored, but matching is
|
|
730
|
+
* otherwise exact.
|
|
731
|
+
* @param modules - Optional subset to search (see {@link getModuleBySymbol}). Bulkheads
|
|
732
|
+
* live in `CORE_MODULES`; narrowing to any other category returns an empty array.
|
|
733
|
+
* @returns The hull's bulkhead modules — five variants, or six on the Caspian Explorer —
|
|
734
|
+
* or an empty array if none are carried for that hull. The input array is not modified.
|
|
735
|
+
* @remarks
|
|
736
|
+
* Bulkheads are the only hull-specific module; everything else fits by slot size, so
|
|
737
|
+
* this does *not* answer "what else can this hull carry" — that is slot layout, which the
|
|
738
|
+
* hull's own record carries. Reach it with {@link getShipByName}, which takes the same
|
|
739
|
+
* display name as this function; {@link getShipSlots} is the same layout keyed by
|
|
740
|
+
* {@link Ship.symbol} instead, and the two differ for most hulls (`"Viper MkIII"` is the
|
|
741
|
+
* record `"Viper"`).
|
|
742
|
+
* @throws {TypeError} If `ship` is present and not a string. A nullish
|
|
743
|
+
* `ship` is a miss, answered the way an unrecognised one is.
|
|
744
|
+
* @example
|
|
745
|
+
* ```ts
|
|
746
|
+
* import { getBulkheadsForShip } from '@elite-dangerous-almanac/core/ships/modules';
|
|
747
|
+
*
|
|
748
|
+
* getBulkheadsForShip('Anaconda').map((m) => m.name);
|
|
749
|
+
* // -> [ 'Lightweight Alloy', 'Reinforced Alloy', 'Military Grade Composite',
|
|
750
|
+
* // 'Mirrored Surface Composite', 'Reactive Surface Composite' ]
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
declare function getBulkheadsForShip(ship: string, modules?: readonly OutfittingModule[]): OutfittingModule[];
|
|
754
|
+
|
|
755
|
+
export { type DamageComponents, type DamageDistribution, type ModuleCategory, type ModuleGuidance, type ModuleMount, type ModuleRating, type OutfittingModule, type OutfittingModuleIdentity, type OutfittingModuleStats, type ProjectileRangeBoundaries, getBulkheadsForShip, getModuleBySymbol, getModulesByName };
|