@alpaca-software/40kdc-data 0.1.1 → 0.1.2
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/dist/abilities-resolver/index.d.ts +9 -0
- package/dist/abilities-resolver/index.d.ts.map +1 -0
- package/dist/abilities-resolver/index.js +9 -0
- package/dist/abilities-resolver/index.js.map +1 -0
- package/dist/abilities-resolver/resolver.d.ts +64 -0
- package/dist/abilities-resolver/resolver.d.ts.map +1 -0
- package/dist/abilities-resolver/resolver.js +135 -0
- package/dist/abilities-resolver/resolver.js.map +1 -0
- package/dist/bundle-schemas.d.ts +1 -0
- package/dist/bundle-schemas.d.ts.map +1 -0
- package/dist/bundle-schemas.js +1 -0
- package/dist/bundle-schemas.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -0
- package/dist/codegen-data.d.ts +1 -0
- package/dist/codegen-data.d.ts.map +1 -0
- package/dist/codegen-data.js +2 -0
- package/dist/codegen-data.js.map +1 -0
- package/dist/commands/import.d.ts +1 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +1 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/translate.d.ts +1 -0
- package/dist/commands/translate.d.ts.map +1 -0
- package/dist/commands/translate.js +1 -0
- package/dist/commands/translate.js.map +1 -0
- package/dist/commands/validate-all.d.ts +1 -0
- package/dist/commands/validate-all.d.ts.map +1 -0
- package/dist/commands/validate-all.js +1 -0
- package/dist/commands/validate-all.js.map +1 -0
- package/dist/commands/validate-core.d.ts +1 -0
- package/dist/commands/validate-core.d.ts.map +1 -0
- package/dist/commands/validate-core.js +1 -0
- package/dist/commands/validate-core.js.map +1 -0
- package/dist/commands/validate-enrichment.d.ts +1 -0
- package/dist/commands/validate-enrichment.d.ts.map +1 -0
- package/dist/commands/validate-enrichment.js +1 -0
- package/dist/commands/validate-enrichment.js.map +1 -0
- package/dist/convert-faction.d.ts +1 -0
- package/dist/convert-faction.d.ts.map +1 -0
- package/dist/convert-faction.js +1 -0
- package/dist/convert-faction.js.map +1 -0
- package/dist/converters/configs/adepta-sororitas.d.ts +1 -0
- package/dist/converters/configs/adepta-sororitas.d.ts.map +1 -0
- package/dist/converters/configs/adepta-sororitas.js +1 -0
- package/dist/converters/configs/adepta-sororitas.js.map +1 -0
- package/dist/converters/configs/adeptus-astartes.d.ts +1 -0
- package/dist/converters/configs/adeptus-astartes.d.ts.map +1 -0
- package/dist/converters/configs/adeptus-astartes.js +1 -0
- package/dist/converters/configs/adeptus-astartes.js.map +1 -0
- package/dist/converters/configs/adeptus-custodes.d.ts +1 -0
- package/dist/converters/configs/adeptus-custodes.d.ts.map +1 -0
- package/dist/converters/configs/adeptus-custodes.js +1 -0
- package/dist/converters/configs/adeptus-custodes.js.map +1 -0
- package/dist/converters/configs/adeptus-mechanicus.d.ts +1 -0
- package/dist/converters/configs/adeptus-mechanicus.d.ts.map +1 -0
- package/dist/converters/configs/adeptus-mechanicus.js +1 -0
- package/dist/converters/configs/adeptus-mechanicus.js.map +1 -0
- package/dist/converters/configs/aeldari.d.ts +1 -0
- package/dist/converters/configs/aeldari.d.ts.map +1 -0
- package/dist/converters/configs/aeldari.js +1 -0
- package/dist/converters/configs/aeldari.js.map +1 -0
- package/dist/converters/configs/agents-of-the-imperium.d.ts +1 -0
- package/dist/converters/configs/agents-of-the-imperium.d.ts.map +1 -0
- package/dist/converters/configs/agents-of-the-imperium.js +1 -0
- package/dist/converters/configs/agents-of-the-imperium.js.map +1 -0
- package/dist/converters/configs/astra-militarum.d.ts +1 -0
- package/dist/converters/configs/astra-militarum.d.ts.map +1 -0
- package/dist/converters/configs/astra-militarum.js +1 -0
- package/dist/converters/configs/astra-militarum.js.map +1 -0
- package/dist/converters/configs/black-templars.d.ts +1 -0
- package/dist/converters/configs/black-templars.d.ts.map +1 -0
- package/dist/converters/configs/black-templars.js +1 -0
- package/dist/converters/configs/black-templars.js.map +1 -0
- package/dist/converters/configs/blood-angels.d.ts +1 -0
- package/dist/converters/configs/blood-angels.d.ts.map +1 -0
- package/dist/converters/configs/blood-angels.js +1 -0
- package/dist/converters/configs/blood-angels.js.map +1 -0
- package/dist/converters/configs/chaos-daemons.d.ts +1 -0
- package/dist/converters/configs/chaos-daemons.d.ts.map +1 -0
- package/dist/converters/configs/chaos-daemons.js +1 -0
- package/dist/converters/configs/chaos-daemons.js.map +1 -0
- package/dist/converters/configs/chaos-knights.d.ts +1 -0
- package/dist/converters/configs/chaos-knights.d.ts.map +1 -0
- package/dist/converters/configs/chaos-knights.js +1 -0
- package/dist/converters/configs/chaos-knights.js.map +1 -0
- package/dist/converters/configs/chaos-space-marines.d.ts +1 -0
- package/dist/converters/configs/chaos-space-marines.d.ts.map +1 -0
- package/dist/converters/configs/chaos-space-marines.js +1 -0
- package/dist/converters/configs/chaos-space-marines.js.map +1 -0
- package/dist/converters/configs/crimson-fists.d.ts +1 -0
- package/dist/converters/configs/crimson-fists.d.ts.map +1 -0
- package/dist/converters/configs/crimson-fists.js +1 -0
- package/dist/converters/configs/crimson-fists.js.map +1 -0
- package/dist/converters/configs/dark-angels.d.ts +1 -0
- package/dist/converters/configs/dark-angels.d.ts.map +1 -0
- package/dist/converters/configs/dark-angels.js +1 -0
- package/dist/converters/configs/dark-angels.js.map +1 -0
- package/dist/converters/configs/death-guard.d.ts +1 -0
- package/dist/converters/configs/death-guard.d.ts.map +1 -0
- package/dist/converters/configs/death-guard.js +1 -0
- package/dist/converters/configs/death-guard.js.map +1 -0
- package/dist/converters/configs/deathwatch.d.ts +1 -0
- package/dist/converters/configs/deathwatch.d.ts.map +1 -0
- package/dist/converters/configs/deathwatch.js +1 -0
- package/dist/converters/configs/deathwatch.js.map +1 -0
- package/dist/converters/configs/drukhari.d.ts +1 -0
- package/dist/converters/configs/drukhari.d.ts.map +1 -0
- package/dist/converters/configs/drukhari.js +1 -0
- package/dist/converters/configs/drukhari.js.map +1 -0
- package/dist/converters/configs/emperors-children.d.ts +1 -0
- package/dist/converters/configs/emperors-children.d.ts.map +1 -0
- package/dist/converters/configs/emperors-children.js +1 -0
- package/dist/converters/configs/emperors-children.js.map +1 -0
- package/dist/converters/configs/genestealer-cults.d.ts +1 -0
- package/dist/converters/configs/genestealer-cults.d.ts.map +1 -0
- package/dist/converters/configs/genestealer-cults.js +1 -0
- package/dist/converters/configs/genestealer-cults.js.map +1 -0
- package/dist/converters/configs/grey-knights.d.ts +1 -0
- package/dist/converters/configs/grey-knights.d.ts.map +1 -0
- package/dist/converters/configs/grey-knights.js +1 -0
- package/dist/converters/configs/grey-knights.js.map +1 -0
- package/dist/converters/configs/imperial-fists.d.ts +1 -0
- package/dist/converters/configs/imperial-fists.d.ts.map +1 -0
- package/dist/converters/configs/imperial-fists.js +1 -0
- package/dist/converters/configs/imperial-fists.js.map +1 -0
- package/dist/converters/configs/imperial-knights.d.ts +1 -0
- package/dist/converters/configs/imperial-knights.d.ts.map +1 -0
- package/dist/converters/configs/imperial-knights.js +1 -0
- package/dist/converters/configs/imperial-knights.js.map +1 -0
- package/dist/converters/configs/iron-hands.d.ts +1 -0
- package/dist/converters/configs/iron-hands.d.ts.map +1 -0
- package/dist/converters/configs/iron-hands.js +1 -0
- package/dist/converters/configs/iron-hands.js.map +1 -0
- package/dist/converters/configs/leagues-of-votann.d.ts +1 -0
- package/dist/converters/configs/leagues-of-votann.d.ts.map +1 -0
- package/dist/converters/configs/leagues-of-votann.js +1 -0
- package/dist/converters/configs/leagues-of-votann.js.map +1 -0
- package/dist/converters/configs/necrons.d.ts +1 -0
- package/dist/converters/configs/necrons.d.ts.map +1 -0
- package/dist/converters/configs/necrons.js +1 -0
- package/dist/converters/configs/necrons.js.map +1 -0
- package/dist/converters/configs/orks.d.ts +1 -0
- package/dist/converters/configs/orks.d.ts.map +1 -0
- package/dist/converters/configs/orks.js +1 -0
- package/dist/converters/configs/orks.js.map +1 -0
- package/dist/converters/configs/raven-guard.d.ts +1 -0
- package/dist/converters/configs/raven-guard.d.ts.map +1 -0
- package/dist/converters/configs/raven-guard.js +1 -0
- package/dist/converters/configs/raven-guard.js.map +1 -0
- package/dist/converters/configs/salamanders.d.ts +1 -0
- package/dist/converters/configs/salamanders.d.ts.map +1 -0
- package/dist/converters/configs/salamanders.js +1 -0
- package/dist/converters/configs/salamanders.js.map +1 -0
- package/dist/converters/configs/space-wolves.d.ts +1 -0
- package/dist/converters/configs/space-wolves.d.ts.map +1 -0
- package/dist/converters/configs/space-wolves.js +1 -0
- package/dist/converters/configs/space-wolves.js.map +1 -0
- package/dist/converters/configs/tau-empire.d.ts +1 -0
- package/dist/converters/configs/tau-empire.d.ts.map +1 -0
- package/dist/converters/configs/tau-empire.js +1 -0
- package/dist/converters/configs/tau-empire.js.map +1 -0
- package/dist/converters/configs/thousand-sons.d.ts +1 -0
- package/dist/converters/configs/thousand-sons.d.ts.map +1 -0
- package/dist/converters/configs/thousand-sons.js +1 -0
- package/dist/converters/configs/thousand-sons.js.map +1 -0
- package/dist/converters/configs/tyranids.d.ts +1 -0
- package/dist/converters/configs/tyranids.d.ts.map +1 -0
- package/dist/converters/configs/tyranids.js +1 -0
- package/dist/converters/configs/tyranids.js.map +1 -0
- package/dist/converters/configs/ultramarines.d.ts +1 -0
- package/dist/converters/configs/ultramarines.d.ts.map +1 -0
- package/dist/converters/configs/ultramarines.js +1 -0
- package/dist/converters/configs/ultramarines.js.map +1 -0
- package/dist/converters/configs/white-scars.d.ts +1 -0
- package/dist/converters/configs/white-scars.d.ts.map +1 -0
- package/dist/converters/configs/white-scars.js +1 -0
- package/dist/converters/configs/white-scars.js.map +1 -0
- package/dist/converters/configs/world-eaters.d.ts +1 -0
- package/dist/converters/configs/world-eaters.d.ts.map +1 -0
- package/dist/converters/configs/world-eaters.js +1 -0
- package/dist/converters/configs/world-eaters.js.map +1 -0
- package/dist/converters/faction-config.d.ts +1 -0
- package/dist/converters/faction-config.d.ts.map +1 -0
- package/dist/converters/faction-config.js +1 -0
- package/dist/converters/faction-config.js.map +1 -0
- package/dist/converters/id-generator.d.ts +1 -0
- package/dist/converters/id-generator.d.ts.map +1 -0
- package/dist/converters/id-generator.js +1 -0
- package/dist/converters/id-generator.js.map +1 -0
- package/dist/converters/keyword-filter.d.ts +1 -0
- package/dist/converters/keyword-filter.d.ts.map +1 -0
- package/dist/converters/keyword-filter.js +1 -0
- package/dist/converters/keyword-filter.js.map +1 -0
- package/dist/converters/stat-parser.d.ts +1 -0
- package/dist/converters/stat-parser.d.ts.map +1 -0
- package/dist/converters/stat-parser.js +1 -0
- package/dist/converters/stat-parser.js.map +1 -0
- package/dist/converters/view-selector.d.ts +1 -0
- package/dist/converters/view-selector.d.ts.map +1 -0
- package/dist/converters/view-selector.js +1 -0
- package/dist/converters/view-selector.js.map +1 -0
- package/dist/converters/weapon-dedup.d.ts +1 -0
- package/dist/converters/weapon-dedup.d.ts.map +1 -0
- package/dist/converters/weapon-dedup.js +1 -0
- package/dist/converters/weapon-dedup.js.map +1 -0
- package/dist/cruncher/buffs.d.ts +184 -0
- package/dist/cruncher/buffs.d.ts.map +1 -0
- package/dist/cruncher/buffs.js +150 -0
- package/dist/cruncher/buffs.js.map +1 -0
- package/dist/cruncher/engine.d.ts +50 -0
- package/dist/cruncher/engine.d.ts.map +1 -0
- package/dist/cruncher/engine.js +312 -0
- package/dist/cruncher/engine.js.map +1 -0
- package/dist/cruncher/from-dsl.d.ts +69 -0
- package/dist/cruncher/from-dsl.d.ts.map +1 -0
- package/dist/cruncher/from-dsl.js +523 -0
- package/dist/cruncher/from-dsl.js.map +1 -0
- package/dist/cruncher/from-keyword.d.ts +35 -0
- package/dist/cruncher/from-keyword.d.ts.map +1 -0
- package/dist/cruncher/from-keyword.js +159 -0
- package/dist/cruncher/from-keyword.js.map +1 -0
- package/dist/cruncher/get-buffs.d.ts +12 -0
- package/dist/cruncher/get-buffs.d.ts.map +1 -0
- package/dist/cruncher/get-buffs.js +7 -0
- package/dist/cruncher/get-buffs.js.map +1 -0
- package/dist/cruncher/index.d.ts +11 -0
- package/dist/cruncher/index.d.ts.map +1 -0
- package/dist/cruncher/index.js +11 -0
- package/dist/cruncher/index.js.map +1 -0
- package/dist/data/bundle.generated.d.ts +1 -0
- package/dist/data/bundle.generated.d.ts.map +1 -0
- package/dist/data/bundle.generated.js +2 -1
- package/dist/data/bundle.generated.js.map +1 -0
- package/dist/data/collection.d.ts +1 -0
- package/dist/data/collection.d.ts.map +1 -0
- package/dist/data/collection.js +1 -0
- package/dist/data/collection.js.map +1 -0
- package/dist/data/dataset.d.ts +54 -2
- package/dist/data/dataset.d.ts.map +1 -0
- package/dist/data/dataset.js +111 -1
- package/dist/data/dataset.js.map +1 -0
- package/dist/data/entities.d.ts +70 -2
- package/dist/data/entities.d.ts.map +1 -0
- package/dist/data/entities.js +122 -0
- package/dist/data/entities.js.map +1 -0
- package/dist/data/index.d.ts +9 -1
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +14 -1
- package/dist/data/index.js.map +1 -0
- package/dist/data/normalize.d.ts +1 -0
- package/dist/data/normalize.d.ts.map +1 -0
- package/dist/data/normalize.js +1 -0
- package/dist/data/normalize.js.map +1 -0
- package/dist/data/roster-resolve.d.ts +33 -0
- package/dist/data/roster-resolve.d.ts.map +1 -0
- package/dist/data/roster-resolve.js +36 -0
- package/dist/data/roster-resolve.js.map +1 -0
- package/dist/data/types.d.ts +4 -1
- package/dist/data/types.d.ts.map +1 -0
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -0
- package/dist/export/helpers.d.ts +33 -0
- package/dist/export/helpers.d.ts.map +1 -0
- package/dist/export/helpers.js +57 -0
- package/dist/export/helpers.js.map +1 -0
- package/dist/export/index.d.ts +21 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +25 -0
- package/dist/export/index.js.map +1 -0
- package/dist/export/newrecruit-json.d.ts +3 -0
- package/dist/export/newrecruit-json.d.ts.map +1 -0
- package/dist/export/newrecruit-json.js +140 -0
- package/dist/export/newrecruit-json.js.map +1 -0
- package/dist/export/newrecruit-simple.d.ts +3 -0
- package/dist/export/newrecruit-simple.d.ts.map +1 -0
- package/dist/export/newrecruit-simple.js +76 -0
- package/dist/export/newrecruit-simple.js.map +1 -0
- package/dist/export/newrecruit-wtc.d.ts +4 -0
- package/dist/export/newrecruit-wtc.d.ts.map +1 -0
- package/dist/export/newrecruit-wtc.js +142 -0
- package/dist/export/newrecruit-wtc.js.map +1 -0
- package/dist/export/roster-json.d.ts +3 -0
- package/dist/export/roster-json.d.ts.map +1 -0
- package/dist/export/roster-json.js +8 -0
- package/dist/export/roster-json.js.map +1 -0
- package/dist/export/serializer.d.ts +27 -0
- package/dist/export/serializer.d.ts.map +1 -0
- package/dist/export/serializer.js +2 -0
- package/dist/export/serializer.js.map +1 -0
- package/dist/gen-conformance.d.ts +1 -0
- package/dist/gen-conformance.d.ts.map +1 -0
- package/dist/gen-conformance.js +73 -12
- package/dist/gen-conformance.js.map +1 -0
- package/dist/generated.d.ts +194 -118
- package/dist/generated.d.ts.map +1 -0
- package/dist/generated.js +1 -0
- package/dist/generated.js.map +1 -0
- package/dist/import/adapter.d.ts +4 -3
- package/dist/import/adapter.d.ts.map +1 -0
- package/dist/import/adapter.js +1 -0
- package/dist/import/adapter.js.map +1 -0
- package/dist/import/decode.d.ts +1 -0
- package/dist/import/decode.d.ts.map +1 -0
- package/dist/import/decode.js +1 -0
- package/dist/import/decode.js.map +1 -0
- package/dist/import/import-roster.d.ts +35 -0
- package/dist/import/import-roster.d.ts.map +1 -0
- package/dist/import/import-roster.js +97 -0
- package/dist/import/import-roster.js.map +1 -0
- package/dist/import/index.d.ts +7 -3
- package/dist/import/index.d.ts.map +1 -0
- package/dist/import/index.js +5 -1
- package/dist/import/index.js.map +1 -0
- package/dist/import/listforge.d.ts +1 -0
- package/dist/import/listforge.d.ts.map +1 -0
- package/dist/import/listforge.js +7 -1
- package/dist/import/listforge.js.map +1 -0
- package/dist/import/newrecruit-json.d.ts +31 -0
- package/dist/import/newrecruit-json.d.ts.map +1 -0
- package/dist/import/newrecruit-json.js +224 -0
- package/dist/import/newrecruit-json.js.map +1 -0
- package/dist/import/newrecruit-simple.d.ts +29 -0
- package/dist/import/newrecruit-simple.d.ts.map +1 -0
- package/dist/import/newrecruit-simple.js +200 -0
- package/dist/import/newrecruit-simple.js.map +1 -0
- package/dist/import/newrecruit-text.d.ts +48 -0
- package/dist/import/newrecruit-text.d.ts.map +1 -0
- package/dist/import/newrecruit-text.js +96 -0
- package/dist/import/newrecruit-text.js.map +1 -0
- package/dist/import/newrecruit-wtc.d.ts +36 -0
- package/dist/import/newrecruit-wtc.d.ts.map +1 -0
- package/dist/import/newrecruit-wtc.js +334 -0
- package/dist/import/newrecruit-wtc.js.map +1 -0
- package/dist/import/resolve.d.ts +3 -2
- package/dist/import/resolve.d.ts.map +1 -0
- package/dist/import/resolve.js +5 -2
- package/dist/import/resolve.js.map +1 -0
- package/dist/import/types.d.ts +11 -1
- package/dist/import/types.d.ts.map +1 -0
- package/dist/import/types.js +1 -0
- package/dist/import/types.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -0
- package/dist/known-support-10e.d.ts +1 -0
- package/dist/known-support-10e.d.ts.map +1 -0
- package/dist/known-support-10e.js +1 -0
- package/dist/known-support-10e.js.map +1 -0
- package/dist/link-abilities.d.ts +41 -0
- package/dist/link-abilities.d.ts.map +1 -0
- package/dist/link-abilities.js +159 -0
- package/dist/link-abilities.js.map +1 -0
- package/dist/migrations/2026-weapon-keywords.d.ts +2 -0
- package/dist/migrations/2026-weapon-keywords.d.ts.map +1 -0
- package/dist/migrations/2026-weapon-keywords.js +243 -0
- package/dist/migrations/2026-weapon-keywords.js.map +1 -0
- package/dist/port-10e-faction.d.ts +1 -0
- package/dist/port-10e-faction.d.ts.map +1 -0
- package/dist/port-10e-faction.js +1 -0
- package/dist/port-10e-faction.js.map +1 -0
- package/dist/report.d.ts +1 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +1 -0
- package/dist/report.js.map +1 -0
- package/dist/rube-goldberg.d.ts +3 -0
- package/dist/rube-goldberg.d.ts.map +1 -0
- package/dist/rube-goldberg.js +109 -0
- package/dist/rube-goldberg.js.map +1 -0
- package/dist/schema-loader.d.ts +1 -0
- package/dist/schema-loader.d.ts.map +1 -0
- package/dist/schema-loader.js +1 -0
- package/dist/schema-loader.js.map +1 -0
- package/dist/validate.d.ts +1 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +2 -0
- package/dist/validate.js.map +1 -0
- package/package.json +7 -2
- package/schemas/core/roster.schema.json +17 -4
- package/schemas/core/weapon-keyword.schema.json +31 -0
- package/schemas/core/weapon.schema.json +22 -1
- package/schemas/enrichment/ability-dsl/effect.schema.json +23 -1
- package/dist/import/import-listforge.d.ts +0 -23
- package/dist/import/import-listforge.js +0 -32
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/** Keywords whose math the engine encodes directly (catalog `effect` is null). */
|
|
2
|
+
const ENGINE_DISPATCH_KEYWORDS = new Set([
|
|
3
|
+
"lethal-hits",
|
|
4
|
+
"sustained-hits",
|
|
5
|
+
"devastating-wounds",
|
|
6
|
+
"anti",
|
|
7
|
+
"melta",
|
|
8
|
+
"rapid-fire",
|
|
9
|
+
"torrent",
|
|
10
|
+
"ignores-cover",
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Convert a single weapon-keyword reference (catalog effect + reference-site
|
|
14
|
+
* parameters) into the buff contributions it makes against `context`.
|
|
15
|
+
*/
|
|
16
|
+
export function buffsFromKeyword(args) {
|
|
17
|
+
const source = {
|
|
18
|
+
kind: "weapon-keyword",
|
|
19
|
+
weaponId: args.weaponId,
|
|
20
|
+
keywordId: args.keywordId,
|
|
21
|
+
};
|
|
22
|
+
if (ENGINE_DISPATCH_KEYWORDS.has(args.keywordId)) {
|
|
23
|
+
const ref = {
|
|
24
|
+
keyword_id: args.keywordId,
|
|
25
|
+
...(args.parameters !== undefined ? { parameters: args.parameters } : {}),
|
|
26
|
+
};
|
|
27
|
+
return [{ source, contribution: { type: "extra-keyword", keywordRef: ref } }];
|
|
28
|
+
}
|
|
29
|
+
if (args.effect === null || args.effect === undefined)
|
|
30
|
+
return [];
|
|
31
|
+
return walk(args.effect, source, args.context);
|
|
32
|
+
}
|
|
33
|
+
function walk(node, source, ctx) {
|
|
34
|
+
if (!isObject(node))
|
|
35
|
+
return [];
|
|
36
|
+
const type = node.type;
|
|
37
|
+
switch (type) {
|
|
38
|
+
case "re-roll":
|
|
39
|
+
return rerollBuffs(node, source);
|
|
40
|
+
case "roll-modifier":
|
|
41
|
+
return rollModifierBuffs(node, source);
|
|
42
|
+
case "feel-no-pain":
|
|
43
|
+
return feelNoPainBuffs(node, source);
|
|
44
|
+
case "keyword-grant":
|
|
45
|
+
return keywordGrantBuffs(node, source);
|
|
46
|
+
case "conditional":
|
|
47
|
+
return conditionalBuffs(node, source, ctx);
|
|
48
|
+
case "sequence":
|
|
49
|
+
return walkChildren(node.steps, source, ctx);
|
|
50
|
+
default:
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function walkChildren(children, source, ctx) {
|
|
55
|
+
if (!Array.isArray(children))
|
|
56
|
+
return [];
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const child of children)
|
|
59
|
+
out.push(...walk(child, source, ctx));
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
function rerollBuffs(node, source) {
|
|
63
|
+
const modifier = node.modifier;
|
|
64
|
+
if (!isObject(modifier))
|
|
65
|
+
return [];
|
|
66
|
+
const roll = modifier.roll;
|
|
67
|
+
const subset = modifier.subset;
|
|
68
|
+
if ((roll === "hit" || roll === "wound" || roll === "save" || roll === "damage") &&
|
|
69
|
+
(subset === "ones" || subset === "all-failures")) {
|
|
70
|
+
return [{ source, contribution: { type: "reroll", roll, subset } }];
|
|
71
|
+
}
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
function rollModifierBuffs(node, source) {
|
|
75
|
+
const modifier = node.modifier;
|
|
76
|
+
if (!isObject(modifier))
|
|
77
|
+
return [];
|
|
78
|
+
const operation = modifier.operation;
|
|
79
|
+
if (operation !== "add")
|
|
80
|
+
return []; // M1 supports additive only; multiplicative effects are out of scope.
|
|
81
|
+
const value = typeof modifier.value === "number" ? modifier.value : NaN;
|
|
82
|
+
if (!Number.isFinite(value))
|
|
83
|
+
return [];
|
|
84
|
+
const roll = modifier.roll;
|
|
85
|
+
switch (roll) {
|
|
86
|
+
case "hit":
|
|
87
|
+
return [{ source, contribution: { type: "hit-mod", value } }];
|
|
88
|
+
case "wound":
|
|
89
|
+
return [{ source, contribution: { type: "wound-mod", value } }];
|
|
90
|
+
case "save":
|
|
91
|
+
return [{ source, contribution: { type: "save-mod", value } }];
|
|
92
|
+
case "damage":
|
|
93
|
+
return [{ source, contribution: { type: "damage-mod", value } }];
|
|
94
|
+
default:
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function feelNoPainBuffs(node, source) {
|
|
99
|
+
const modifier = node.modifier;
|
|
100
|
+
if (!isObject(modifier))
|
|
101
|
+
return [];
|
|
102
|
+
const threshold = typeof modifier.threshold === "number" ? modifier.threshold : NaN;
|
|
103
|
+
if (!Number.isFinite(threshold))
|
|
104
|
+
return [];
|
|
105
|
+
return [{ source, contribution: { type: "feel-no-pain", threshold } }];
|
|
106
|
+
}
|
|
107
|
+
function keywordGrantBuffs(node, source) {
|
|
108
|
+
const modifier = node.modifier;
|
|
109
|
+
if (!isObject(modifier))
|
|
110
|
+
return [];
|
|
111
|
+
const id = modifier.keyword_id ?? modifier.id;
|
|
112
|
+
if (typeof id !== "string" || id === "")
|
|
113
|
+
return [];
|
|
114
|
+
const params = isObject(modifier.parameters) ? modifier.parameters : undefined;
|
|
115
|
+
const ref = {
|
|
116
|
+
keyword_id: id,
|
|
117
|
+
...(params !== undefined ? { parameters: params } : {}),
|
|
118
|
+
};
|
|
119
|
+
return [{ source, contribution: { type: "extra-keyword", keywordRef: ref } }];
|
|
120
|
+
}
|
|
121
|
+
function conditionalBuffs(node, source, ctx) {
|
|
122
|
+
const condition = node.condition;
|
|
123
|
+
const effect = node.effect;
|
|
124
|
+
if (!isObject(condition))
|
|
125
|
+
return [];
|
|
126
|
+
const negated = condition.negated === true;
|
|
127
|
+
const verdict = evaluateCondition(condition, ctx);
|
|
128
|
+
if (verdict === "unknown")
|
|
129
|
+
return [];
|
|
130
|
+
const active = negated ? !verdict : verdict;
|
|
131
|
+
if (!active)
|
|
132
|
+
return [];
|
|
133
|
+
return walk(effect, source, ctx);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns true/false when the engine can evaluate the condition against
|
|
137
|
+
* `ctx`; "unknown" when the condition references state the M1 engine has no
|
|
138
|
+
* channel for (the buff is then dropped — M2's diagnostic surface owns the
|
|
139
|
+
* "cannot auto-apply" reporting).
|
|
140
|
+
*/
|
|
141
|
+
function evaluateCondition(condition, ctx) {
|
|
142
|
+
switch (condition.type) {
|
|
143
|
+
case "remained-stationary":
|
|
144
|
+
return ctx.attackerStationary === true;
|
|
145
|
+
case "target-has-keyword": {
|
|
146
|
+
const parameters = isObject(condition.parameters) ? condition.parameters : {};
|
|
147
|
+
const kw = parameters.keyword;
|
|
148
|
+
if (typeof kw !== "string")
|
|
149
|
+
return "unknown";
|
|
150
|
+
return (ctx.targetKeywords ?? []).includes(kw.toLowerCase());
|
|
151
|
+
}
|
|
152
|
+
default:
|
|
153
|
+
return "unknown";
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function isObject(value) {
|
|
157
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=from-keyword.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-keyword.js","sourceRoot":"","sources":["../../src/cruncher/from-keyword.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Translate a weapon-keyword catalog entry into the Buff stack it contributes\n * for a given reference-site parameter set and engine context.\n *\n * Two paths converge here:\n *\n * 1. **DSL walk**, for keywords whose catalog `effect` is non-null\n * (`twin-linked`, `heavy`). The walker handles a deliberately small subset\n * of nodes — `re-roll`, `roll-modifier`, `conditional`-on-the-conditions\n * the engine knows about — and produces `Buff`s with\n * `source.kind = \"weapon-keyword\"`.\n *\n * 2. **Id dispatch**, for the eight rules whose catalog `effect` is null\n * because the DSL has no primitive for them yet — `lethal-hits`,\n * `sustained-hits`, `devastating-wounds`, `anti`, `melta`, `rapid-fire`,\n * `torrent`, `ignores-cover`. These are surfaced as `extra-keyword` buffs\n * so the engine can read them out of `ResolvedModifiers.extraKeywords`\n * and dispatch its math directly.\n *\n * Unrecognised nodes drop silently in M1 — diagnostic surfacing belongs to\n * M2's broader ability translator.\n */\nimport type { Buff, BuffSource, EngineContext, WeaponKeywordRef } from \"./buffs.js\";\n\n/** Keywords whose math the engine encodes directly (catalog `effect` is null). */\nconst ENGINE_DISPATCH_KEYWORDS = new Set([\n \"lethal-hits\",\n \"sustained-hits\",\n \"devastating-wounds\",\n \"anti\",\n \"melta\",\n \"rapid-fire\",\n \"torrent\",\n \"ignores-cover\",\n]);\n\n/**\n * Convert a single weapon-keyword reference (catalog effect + reference-site\n * parameters) into the buff contributions it makes against `context`.\n */\nexport function buffsFromKeyword(args: {\n keywordId: string;\n weaponId: string;\n effect: unknown;\n parameters?: Record<string, unknown>;\n context: EngineContext;\n}): Buff[] {\n const source: BuffSource = {\n kind: \"weapon-keyword\",\n weaponId: args.weaponId,\n keywordId: args.keywordId,\n };\n\n if (ENGINE_DISPATCH_KEYWORDS.has(args.keywordId)) {\n const ref: WeaponKeywordRef = {\n keyword_id: args.keywordId,\n ...(args.parameters !== undefined ? { parameters: args.parameters } : {}),\n };\n return [{ source, contribution: { type: \"extra-keyword\", keywordRef: ref } }];\n }\n\n if (args.effect === null || args.effect === undefined) return [];\n return walk(args.effect, source, args.context);\n}\n\nfunction walk(node: unknown, source: BuffSource, ctx: EngineContext): Buff[] {\n if (!isObject(node)) return [];\n const type = node.type;\n\n switch (type) {\n case \"re-roll\":\n return rerollBuffs(node, source);\n case \"roll-modifier\":\n return rollModifierBuffs(node, source);\n case \"feel-no-pain\":\n return feelNoPainBuffs(node, source);\n case \"keyword-grant\":\n return keywordGrantBuffs(node, source);\n case \"conditional\":\n return conditionalBuffs(node, source, ctx);\n case \"sequence\":\n return walkChildren((node as { steps?: unknown[] }).steps, source, ctx);\n default:\n return [];\n }\n}\n\nfunction walkChildren(children: unknown[] | undefined, source: BuffSource, ctx: EngineContext): Buff[] {\n if (!Array.isArray(children)) return [];\n const out: Buff[] = [];\n for (const child of children) out.push(...walk(child, source, ctx));\n return out;\n}\n\nfunction rerollBuffs(node: Record<string, unknown>, source: BuffSource): Buff[] {\n const modifier = node.modifier;\n if (!isObject(modifier)) return [];\n const roll = modifier.roll;\n const subset = modifier.subset;\n if (\n (roll === \"hit\" || roll === \"wound\" || roll === \"save\" || roll === \"damage\") &&\n (subset === \"ones\" || subset === \"all-failures\")\n ) {\n return [{ source, contribution: { type: \"reroll\", roll, subset } }];\n }\n return [];\n}\n\nfunction rollModifierBuffs(node: Record<string, unknown>, source: BuffSource): Buff[] {\n const modifier = node.modifier;\n if (!isObject(modifier)) return [];\n const operation = modifier.operation;\n if (operation !== \"add\") return []; // M1 supports additive only; multiplicative effects are out of scope.\n const value = typeof modifier.value === \"number\" ? modifier.value : NaN;\n if (!Number.isFinite(value)) return [];\n const roll = modifier.roll;\n switch (roll) {\n case \"hit\":\n return [{ source, contribution: { type: \"hit-mod\", value } }];\n case \"wound\":\n return [{ source, contribution: { type: \"wound-mod\", value } }];\n case \"save\":\n return [{ source, contribution: { type: \"save-mod\", value } }];\n case \"damage\":\n return [{ source, contribution: { type: \"damage-mod\", value } }];\n default:\n return [];\n }\n}\n\nfunction feelNoPainBuffs(node: Record<string, unknown>, source: BuffSource): Buff[] {\n const modifier = node.modifier;\n if (!isObject(modifier)) return [];\n const threshold = typeof modifier.threshold === \"number\" ? modifier.threshold : NaN;\n if (!Number.isFinite(threshold)) return [];\n return [{ source, contribution: { type: \"feel-no-pain\", threshold } }];\n}\n\nfunction keywordGrantBuffs(node: Record<string, unknown>, source: BuffSource): Buff[] {\n const modifier = node.modifier;\n if (!isObject(modifier)) return [];\n const id = modifier.keyword_id ?? modifier.id;\n if (typeof id !== \"string\" || id === \"\") return [];\n const params = isObject(modifier.parameters) ? modifier.parameters : undefined;\n const ref: WeaponKeywordRef = {\n keyword_id: id,\n ...(params !== undefined ? { parameters: params } : {}),\n };\n return [{ source, contribution: { type: \"extra-keyword\", keywordRef: ref } }];\n}\n\nfunction conditionalBuffs(\n node: Record<string, unknown>,\n source: BuffSource,\n ctx: EngineContext,\n): Buff[] {\n const condition = node.condition;\n const effect = node.effect;\n if (!isObject(condition)) return [];\n const negated = condition.negated === true;\n const verdict = evaluateCondition(condition, ctx);\n if (verdict === \"unknown\") return [];\n const active = negated ? !verdict : verdict;\n if (!active) return [];\n return walk(effect, source, ctx);\n}\n\n/**\n * Returns true/false when the engine can evaluate the condition against\n * `ctx`; \"unknown\" when the condition references state the M1 engine has no\n * channel for (the buff is then dropped — M2's diagnostic surface owns the\n * \"cannot auto-apply\" reporting).\n */\nfunction evaluateCondition(\n condition: Record<string, unknown>,\n ctx: EngineContext,\n): boolean | \"unknown\" {\n switch (condition.type) {\n case \"remained-stationary\":\n return ctx.attackerStationary === true;\n case \"target-has-keyword\": {\n const parameters = isObject(condition.parameters) ? condition.parameters : {};\n const kw = parameters.keyword;\n if (typeof kw !== \"string\") return \"unknown\";\n return (ctx.targetKeywords ?? []).includes(kw.toLowerCase());\n }\n default:\n return \"unknown\";\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Concatenate the buff contributions from every item in a list of "has-buffs"
|
|
3
|
+
* objects. Lower-level utility behind {@link Dataset.buffsFor}; surfaced as
|
|
4
|
+
* its own export so callers who want to wire their stack differently can
|
|
5
|
+
* still keep the one-liner ergonomics.
|
|
6
|
+
*/
|
|
7
|
+
import type { Buff } from "./buffs.js";
|
|
8
|
+
export interface HasBuffs {
|
|
9
|
+
getBuffs(...args: unknown[]): Buff[];
|
|
10
|
+
}
|
|
11
|
+
export declare function getBuffs(items: HasBuffs[], ...args: unknown[]): Buff[];
|
|
12
|
+
//# sourceMappingURL=get-buffs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-buffs.d.ts","sourceRoot":"","sources":["../../src/cruncher/get-buffs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,QAAQ;IAIvB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;CACtC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAItE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-buffs.js","sourceRoot":"","sources":["../../src/cruncher/get-buffs.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,QAAQ,CAAC,KAAiB,EAAE,GAAG,IAAe;IAC5D,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Concatenate the buff contributions from every item in a list of \"has-buffs\"\n * objects. Lower-level utility behind {@link Dataset.buffsFor}; surfaced as\n * its own export so callers who want to wire their stack differently can\n * still keep the one-liner ergonomics.\n */\nimport type { Buff } from \"./buffs.js\";\n\nexport interface HasBuffs {\n // The runtime contract is loose on purpose: any of the package's view\n // classes — WeaponView, WeaponKeywordView, AbilityView (M2), or anything\n // a caller hand-rolls — can satisfy it.\n getBuffs(...args: unknown[]): Buff[];\n}\n\nexport function getBuffs(items: HasBuffs[], ...args: unknown[]): Buff[] {\n const out: Buff[] = [];\n for (const item of items) out.push(...item.getBuffs(...args));\n return out;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The damage-projection engine: pure-function math over schema profiles and
|
|
3
|
+
* a flat {@link Buff} stack.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
export { resolveBuffs, type Buff, type BuffApplicability, type BuffContribution, type BuffSource, type EngineContext, type ResolveContext, type ResolvedModifiers, type WeaponKeywordRef, } from "./buffs.js";
|
|
8
|
+
export { buffsFromKeyword } from "./from-keyword.js";
|
|
9
|
+
export { getBuffs, type HasBuffs } from "./get-buffs.js";
|
|
10
|
+
export { crunch, type AttackProfileRef, type EngineInput, type EngineOutput, type Stage, type TargetProfileRef, } from "./engine.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cruncher/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,YAAY,EACZ,KAAK,IAAI,EACT,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EACL,MAAM,EACN,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The damage-projection engine: pure-function math over schema profiles and
|
|
3
|
+
* a flat {@link Buff} stack.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
export { resolveBuffs, } from "./buffs.js";
|
|
8
|
+
export { buffsFromKeyword } from "./from-keyword.js";
|
|
9
|
+
export { getBuffs } from "./get-buffs.js";
|
|
10
|
+
export { crunch, } from "./engine.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cruncher/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,YAAY,GASb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAC;AACzD,OAAO,EACL,MAAM,GAMP,MAAM,aAAa,CAAC","sourcesContent":["/**\n * The damage-projection engine: pure-function math over schema profiles and\n * a flat {@link Buff} stack.\n *\n * @packageDocumentation\n */\nexport {\n resolveBuffs,\n type Buff,\n type BuffApplicability,\n type BuffContribution,\n type BuffSource,\n type EngineContext,\n type ResolveContext,\n type ResolvedModifiers,\n type WeaponKeywordRef,\n} from \"./buffs.js\";\nexport { buffsFromKeyword } from \"./from-keyword.js\";\nexport { getBuffs, type HasBuffs } from \"./get-buffs.js\";\nexport {\n crunch,\n type AttackProfileRef,\n type EngineInput,\n type EngineOutput,\n type Stage,\n type TargetProfileRef,\n} from \"./engine.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.generated.d.ts","sourceRoot":"","sources":["../../src/data/bundle.generated.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,EAAE,OAA0C,CAAC"}
|