@archivist-gg/dnd5e 0.1.0
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 +21 -0
- package/LICENSES/SRD.md +37 -0
- package/README.md +65 -0
- package/dist/armor/armor.codec.d.ts +10 -0
- package/dist/armor/armor.codec.js +8 -0
- package/dist/armor/armor.entity-type.d.ts +2 -0
- package/dist/armor/armor.parser.d.ts +3 -0
- package/dist/armor/armor.parser.js +7 -0
- package/dist/armor/armor.schema.d.ts +25 -0
- package/dist/armor/armor.schema.js +6 -0
- package/dist/armor/armor.types.d.ts +26 -0
- package/dist/armor/armor.types.js +0 -0
- package/dist/background/background.codec.d.ts +9 -0
- package/dist/background/background.codec.js +11 -0
- package/dist/background/background.entity-type.d.ts +2 -0
- package/dist/background/background.parser.d.ts +3 -0
- package/dist/background/background.parser.js +10 -0
- package/dist/background/background.schema.d.ts +74 -0
- package/dist/background/background.schema.js +9 -0
- package/dist/background/background.types.d.ts +52 -0
- package/dist/background/background.types.js +0 -0
- package/dist/chunk-24GFQU7T.js +18 -0
- package/dist/chunk-3DZ74AKK.js +28 -0
- package/dist/chunk-3TM34RSJ.js +23 -0
- package/dist/chunk-3TRGRSCH.js +8 -0
- package/dist/chunk-4C2KOKLF.js +185 -0
- package/dist/chunk-4F6AIZ36.js +19 -0
- package/dist/chunk-4SSDYJS2.js +86 -0
- package/dist/chunk-4TIJKN6O.js +37 -0
- package/dist/chunk-537BHVSH.js +18 -0
- package/dist/chunk-5INR4NSL.js +18 -0
- package/dist/chunk-5XUXXAQJ.js +30 -0
- package/dist/chunk-656QCX4U.js +22 -0
- package/dist/chunk-66XXW2Z2.js +133 -0
- package/dist/chunk-6NK2MUD3.js +114 -0
- package/dist/chunk-6PXE7T7C.js +79 -0
- package/dist/chunk-7P65Q426.js +158 -0
- package/dist/chunk-A7T5L7SS.js +83 -0
- package/dist/chunk-AFKTJXRA.js +39 -0
- package/dist/chunk-B7UXKNLD.js +46 -0
- package/dist/chunk-BAXWWGFJ.js +45 -0
- package/dist/chunk-BH6AMZVY.js +25 -0
- package/dist/chunk-CDW7R2QT.js +62 -0
- package/dist/chunk-DABBCYTT.js +68 -0
- package/dist/chunk-DC74TZNA.js +46 -0
- package/dist/chunk-DNAJRMNN.js +68 -0
- package/dist/chunk-DRNZJNJP.js +19 -0
- package/dist/chunk-FEOB24KP.js +18 -0
- package/dist/chunk-FFULAF2P.js +63 -0
- package/dist/chunk-FUK7QSN5.js +19 -0
- package/dist/chunk-GIOH5JB5.js +19 -0
- package/dist/chunk-GJOI2GHP.js +25 -0
- package/dist/chunk-GZ46OVGZ.js +31 -0
- package/dist/chunk-HCP3GMHS.js +44 -0
- package/dist/chunk-IDTDACM6.js +19 -0
- package/dist/chunk-IKSMX4TN.js +0 -0
- package/dist/chunk-IXZXFFFW.js +269 -0
- package/dist/chunk-J2RYSZMQ.js +16 -0
- package/dist/chunk-JEYQU3JT.js +36 -0
- package/dist/chunk-LSLSG67V.js +31 -0
- package/dist/chunk-LWFTHJIE.js +24 -0
- package/dist/chunk-MDEJHMKK.js +52 -0
- package/dist/chunk-N2JE7BWL.js +81 -0
- package/dist/chunk-NAEPSZAM.js +88 -0
- package/dist/chunk-NXR3BD2V.js +90 -0
- package/dist/chunk-PKC77VZP.js +18 -0
- package/dist/chunk-PMADYMUI.js +19 -0
- package/dist/chunk-PTXBIDG7.js +63 -0
- package/dist/chunk-PZOWBI3B.js +49 -0
- package/dist/chunk-QQ5W2AZP.js +515 -0
- package/dist/chunk-QS5L5YTJ.js +24 -0
- package/dist/chunk-QYZV2MQA.js +97 -0
- package/dist/chunk-R2ZV233X.js +233 -0
- package/dist/chunk-RAWJTA45.js +271 -0
- package/dist/chunk-RSDRMH54.js +18 -0
- package/dist/chunk-RVYYKYFL.js +18 -0
- package/dist/chunk-SSXBYF3P.js +18 -0
- package/dist/chunk-TJCNX6UZ.js +521 -0
- package/dist/chunk-TZK36BU7.js +38 -0
- package/dist/chunk-UC4FE5X3.js +65 -0
- package/dist/chunk-WP2CX2JO.js +235 -0
- package/dist/chunk-WYGD2UGN.js +14 -0
- package/dist/chunk-XJNECUPT.js +31 -0
- package/dist/chunk-XURS6Q6Q.js +127 -0
- package/dist/chunk-Y4I74YEG.js +33 -0
- package/dist/chunk-Z4TL2V7S.js +18 -0
- package/dist/chunk-Z6GXV2GO.js +121 -0
- package/dist/chunk-ZLG6FQFB.js +237 -0
- package/dist/chunk-ZMR77DDL.js +18 -0
- package/dist/class/class.codec.d.ts +10 -0
- package/dist/class/class.codec.js +15 -0
- package/dist/class/class.entity-type.d.ts +2 -0
- package/dist/class/class.parser.d.ts +3 -0
- package/dist/class/class.parser.js +14 -0
- package/dist/class/class.schema.d.ts +202 -0
- package/dist/class/class.schema.js +13 -0
- package/dist/class/class.slug.d.ts +11 -0
- package/dist/class/class.slug.js +8 -0
- package/dist/class/class.types.d.ts +74 -0
- package/dist/class/class.types.js +0 -0
- package/dist/data-srd/index.generated.d.ts +7 -0
- package/dist/data-srd/index.generated.js +146 -0
- package/dist/dnd/constants.d.ts +16 -0
- package/dist/dnd/constants.js +36 -0
- package/dist/dnd/formula-tags.d.ts +16 -0
- package/dist/dnd/formula-tags.js +119 -0
- package/dist/dnd/math.d.ts +24 -0
- package/dist/dnd/math.js +35 -0
- package/dist/dnd/prose-tags.d.ts +16 -0
- package/dist/dnd/prose-tags.js +18 -0
- package/dist/dnd/resource-die.d.ts +6 -0
- package/dist/dnd/resource-die.js +17 -0
- package/dist/dnd/resource-formula.d.ts +41 -0
- package/dist/dnd/resource-formula.js +159 -0
- package/dist/dnd/srd-tag-converter.d.ts +44 -0
- package/dist/dnd/srd-tag-converter.js +12 -0
- package/dist/dnd/tag-grammar.d.ts +19 -0
- package/dist/dnd/tag-grammar.js +12 -0
- package/dist/encounter/encounter.ai-schema.d.ts +29 -0
- package/dist/encounter/encounter.ai-schema.js +8 -0
- package/dist/encounter/encounter.entity-type.d.ts +2 -0
- package/dist/encounter/encounter.generatable.d.ts +2 -0
- package/dist/entities/base-item-resolver.d.ts +21 -0
- package/dist/entities/base-item-resolver.js +9 -0
- package/dist/entities/slug.d.ts +5 -0
- package/dist/entities/slug.js +6 -0
- package/dist/feat/feat.codec.d.ts +9 -0
- package/dist/feat/feat.codec.js +10 -0
- package/dist/feat/feat.entity-type.d.ts +2 -0
- package/dist/feat/feat.parser.d.ts +3 -0
- package/dist/feat/feat.parser.js +9 -0
- package/dist/feat/feat.schema.d.ts +194 -0
- package/dist/feat/feat.schema.js +8 -0
- package/dist/feat/feat.types.d.ts +42 -0
- package/dist/feat/feat.types.js +0 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +139149 -0
- package/dist/inline-tag-parser.d.ts +11 -0
- package/dist/inline-tag-parser.js +6 -0
- package/dist/item/item.actions-map.d.ts +41 -0
- package/dist/item/item.actions-map.js +85 -0
- package/dist/item/item.ai-schema.d.ts +35 -0
- package/dist/item/item.ai-schema.js +6 -0
- package/dist/item/item.attunement.d.ts +18 -0
- package/dist/item/item.attunement.js +12 -0
- package/dist/item/item.bonuses.d.ts +2 -0
- package/dist/item/item.bonuses.js +7 -0
- package/dist/item/item.codec.d.ts +3 -0
- package/dist/item/item.codec.js +8 -0
- package/dist/item/item.conditions.d.ts +10 -0
- package/dist/item/item.conditions.js +8 -0
- package/dist/item/item.conditions.types.d.ts +28 -0
- package/dist/item/item.conditions.types.js +0 -0
- package/dist/item/item.enrichment.d.ts +4 -0
- package/dist/item/item.enrichment.js +9 -0
- package/dist/item/item.entity-type.d.ts +2 -0
- package/dist/item/item.generatable.d.ts +2 -0
- package/dist/item/item.parser.d.ts +3 -0
- package/dist/item/item.parser.js +7 -0
- package/dist/item/item.schema.d.ts +174 -0
- package/dist/item/item.schema.js +8 -0
- package/dist/item/item.types.d.ts +108 -0
- package/dist/item/item.types.js +0 -0
- package/dist/monster/monster.ai-schema.d.ts +67 -0
- package/dist/monster/monster.ai-schema.js +6 -0
- package/dist/monster/monster.codec.d.ts +13 -0
- package/dist/monster/monster.enrichment.d.ts +10 -0
- package/dist/monster/monster.enrichment.js +19 -0
- package/dist/monster/monster.entity-type.d.ts +2 -0
- package/dist/monster/monster.generatable.d.ts +2 -0
- package/dist/monster/monster.parser.d.ts +3 -0
- package/dist/monster/monster.parser.js +6 -0
- package/dist/monster/monster.resolve.d.ts +10 -0
- package/dist/monster/monster.types.d.ts +29 -0
- package/dist/monster/monster.types.js +1 -0
- package/dist/npc/npc.ai-schema.d.ts +6 -0
- package/dist/npc/npc.entity-type.d.ts +2 -0
- package/dist/npc/npc.generatable.d.ts +2 -0
- package/dist/optional-feature/optional-feature.codec.d.ts +14 -0
- package/dist/optional-feature/optional-feature.codec.js +11 -0
- package/dist/optional-feature/optional-feature.entity-type.d.ts +2 -0
- package/dist/optional-feature/optional-feature.parser.d.ts +3 -0
- package/dist/optional-feature/optional-feature.parser.js +10 -0
- package/dist/optional-feature/optional-feature.schema.d.ts +236 -0
- package/dist/optional-feature/optional-feature.schema.js +9 -0
- package/dist/pack.d.ts +11 -0
- package/dist/pc/conditions.constants.d.ts +3 -0
- package/dist/pc/conditions.constants.js +8 -0
- package/dist/pc/decision-recognizer.d.ts +4 -0
- package/dist/pc/decision-recognizer.js +8 -0
- package/dist/pc/pc.conditions.d.ts +3 -0
- package/dist/pc/pc.conditions.js +6 -0
- package/dist/pc/pc.decision-engine.d.ts +97 -0
- package/dist/pc/pc.decision-engine.js +19 -0
- package/dist/pc/pc.equipment.d.ts +12 -0
- package/dist/pc/pc.equipment.js +15 -0
- package/dist/pc/pc.feature-effects.d.ts +95 -0
- package/dist/pc/pc.feature-effects.js +9 -0
- package/dist/pc/pc.formula-context.d.ts +4 -0
- package/dist/pc/pc.formula-context.js +11 -0
- package/dist/pc/pc.parser.d.ts +3 -0
- package/dist/pc/pc.parser.js +41 -0
- package/dist/pc/pc.pools.d.ts +12 -0
- package/dist/pc/pc.pools.js +15 -0
- package/dist/pc/pc.proficiencies.d.ts +8 -0
- package/dist/pc/pc.proficiencies.js +47 -0
- package/dist/pc/pc.proficiency-query.d.ts +11 -0
- package/dist/pc/pc.proficiency-query.js +17 -0
- package/dist/pc/pc.recalc.d.ts +105 -0
- package/dist/pc/pc.recalc.js +662 -0
- package/dist/pc/pc.resolver.d.ts +34 -0
- package/dist/pc/pc.resolver.js +267 -0
- package/dist/pc/pc.resource-seed.d.ts +10 -0
- package/dist/pc/pc.resource-seed.js +40 -0
- package/dist/pc/pc.rest.d.ts +23 -0
- package/dist/pc/pc.rest.js +128 -0
- package/dist/pc/pc.schema.d.ts +294 -0
- package/dist/pc/pc.schema.js +7 -0
- package/dist/pc/pc.slotting.d.ts +22 -0
- package/dist/pc/pc.slotting.js +20 -0
- package/dist/pc/pc.spellcasting.d.ts +56 -0
- package/dist/pc/pc.spellcasting.js +16 -0
- package/dist/pc/pc.table-column.d.ts +12 -0
- package/dist/pc/pc.table-column.js +8 -0
- package/dist/pc/pc.types.d.ts +514 -0
- package/dist/pc/pc.types.js +0 -0
- package/dist/race/race.codec.d.ts +9 -0
- package/dist/race/race.codec.js +13 -0
- package/dist/race/race.entity-type.d.ts +2 -0
- package/dist/race/race.parser.d.ts +3 -0
- package/dist/race/race.parser.js +12 -0
- package/dist/race/race.schema.d.ts +67 -0
- package/dist/race/race.schema.js +11 -0
- package/dist/race/race.types.d.ts +44 -0
- package/dist/race/race.types.js +0 -0
- package/dist/schemas/attack-schema.d.ts +38 -0
- package/dist/schemas/choice-schema.d.ts +5 -0
- package/dist/schemas/choice-schema.js +7 -0
- package/dist/schemas/duration-schema.d.ts +13 -0
- package/dist/schemas/duration-schema.js +6 -0
- package/dist/schemas/equipment-grant-schema.d.ts +6 -0
- package/dist/schemas/equipment-grant-schema.js +12 -0
- package/dist/schemas/feature-effect-schema.d.ts +131 -0
- package/dist/schemas/feature-effect-schema.js +6 -0
- package/dist/schemas/feature-schema.d.ts +2 -0
- package/dist/schemas/feature-schema.js +10 -0
- package/dist/schemas/index.d.ts +6 -0
- package/dist/schemas/resource-schema.d.ts +95 -0
- package/dist/schemas/resource-schema.js +12 -0
- package/dist/schemas/selection-pool-schema.d.ts +34 -0
- package/dist/schemas/selection-pool-schema.js +10 -0
- package/dist/spell/spell.access.d.ts +15 -0
- package/dist/spell/spell.access.js +25 -0
- package/dist/spell/spell.ai-schema.d.ts +24 -0
- package/dist/spell/spell.ai-schema.js +6 -0
- package/dist/spell/spell.codec.d.ts +3 -0
- package/dist/spell/spell.codec.js +8 -0
- package/dist/spell/spell.enrichment.d.ts +2 -0
- package/dist/spell/spell.enrichment.js +9 -0
- package/dist/spell/spell.entity-type.d.ts +2 -0
- package/dist/spell/spell.filter.d.ts +15 -0
- package/dist/spell/spell.filter.js +87 -0
- package/dist/spell/spell.generatable.d.ts +2 -0
- package/dist/spell/spell.parser.d.ts +3 -0
- package/dist/spell/spell.parser.js +7 -0
- package/dist/spell/spell.scaling.d.ts +14 -0
- package/dist/spell/spell.scaling.js +28 -0
- package/dist/spell/spell.schema.d.ts +31 -0
- package/dist/spell/spell.schema.js +6 -0
- package/dist/spell/spell.types.d.ts +25 -0
- package/dist/spell/spell.types.js +0 -0
- package/dist/srd-store.d.ts +53 -0
- package/dist/subclass/subclass.codec.d.ts +11 -0
- package/dist/subclass/subclass.codec.js +14 -0
- package/dist/subclass/subclass.entity-type.d.ts +2 -0
- package/dist/subclass/subclass.parser.d.ts +3 -0
- package/dist/subclass/subclass.parser.js +13 -0
- package/dist/subclass/subclass.schema.d.ts +118 -0
- package/dist/subclass/subclass.schema.js +12 -0
- package/dist/subclass/subclass.types.d.ts +20 -0
- package/dist/subclass/subclass.types.js +0 -0
- package/dist/types/abilities.d.ts +8 -0
- package/dist/types/abilities.js +0 -0
- package/dist/types/ac.d.ts +5 -0
- package/dist/types/attack.d.ts +22 -0
- package/dist/types/attack.js +0 -0
- package/dist/types/casting-option.d.ts +14 -0
- package/dist/types/casting-option.js +0 -0
- package/dist/types/choice.d.ts +66 -0
- package/dist/types/choice.js +6 -0
- package/dist/types/edition.d.ts +4 -0
- package/dist/types/edition.js +0 -0
- package/dist/types/equipment-grant.d.ts +41 -0
- package/dist/types/equipment-grant.js +0 -0
- package/dist/types/feature-effect.d.ts +79 -0
- package/dist/types/feature-effect.js +0 -0
- package/dist/types/feature.d.ts +41 -0
- package/dist/types/feature.js +0 -0
- package/dist/types/formula-context.d.ts +7 -0
- package/dist/types/formula-context.js +0 -0
- package/dist/types/hp.d.ts +4 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/item-conditions.types.d.ts +63 -0
- package/dist/types/item-conditions.types.js +0 -0
- package/dist/types/optional-feature.types.d.ts +60 -0
- package/dist/types/optional-feature.types.js +0 -0
- package/dist/types/resource.d.ts +44 -0
- package/dist/types/resource.js +0 -0
- package/dist/types/selection-pool.d.ts +37 -0
- package/dist/types/selection-pool.js +0 -0
- package/dist/types/speed.d.ts +8 -0
- package/dist/weapon/weapon.codec.d.ts +12 -0
- package/dist/weapon/weapon.codec.js +8 -0
- package/dist/weapon/weapon.entity-type.d.ts +2 -0
- package/dist/weapon/weapon.parser.d.ts +3 -0
- package/dist/weapon/weapon.parser.js +7 -0
- package/dist/weapon/weapon.schema.d.ts +34 -0
- package/dist/weapon/weapon.schema.js +6 -0
- package/dist/weapon/weapon.types.d.ts +36 -0
- package/dist/weapon/weapon.types.js +0 -0
- package/package.json +32 -0
- package/src/data-srd/ATTRIBUTION.md +2 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__matchesFilterForTest,
|
|
3
|
+
bareEntitySlug,
|
|
4
|
+
buildDecisionLedger,
|
|
5
|
+
collectChosenAbilityPoints,
|
|
6
|
+
collectChosenProficiencies,
|
|
7
|
+
wikilinkTailSlug
|
|
8
|
+
} from "../chunk-TJCNX6UZ.js";
|
|
9
|
+
import "../chunk-BH6AMZVY.js";
|
|
10
|
+
import "../chunk-JEYQU3JT.js";
|
|
11
|
+
import "../chunk-WP2CX2JO.js";
|
|
12
|
+
export {
|
|
13
|
+
__matchesFilterForTest,
|
|
14
|
+
bareEntitySlug,
|
|
15
|
+
buildDecisionLedger,
|
|
16
|
+
collectChosenAbilityPoints,
|
|
17
|
+
collectChosenProficiencies,
|
|
18
|
+
wikilinkTailSlug
|
|
19
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EntityRegistry } from "@archivist-gg/core";
|
|
2
|
+
import type { Ability } from "@archivist-gg/dnd5e";
|
|
3
|
+
import type { AppliedBonuses, DerivedEquipment, ResolvedCharacter, ProficiencySet } from "./pc.types.js";
|
|
4
|
+
interface ProficienciesForQuery {
|
|
5
|
+
armor: ProficiencySet;
|
|
6
|
+
weapons: ProficiencySet;
|
|
7
|
+
tools: ProficiencySet;
|
|
8
|
+
}
|
|
9
|
+
export declare function emptyAppliedBonuses(): AppliedBonuses;
|
|
10
|
+
export declare function computeAppliedBonuses(resolved: ResolvedCharacter, _profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[]): AppliedBonuses;
|
|
11
|
+
export declare function computeSlotsAndAttacks(resolved: ResolvedCharacter, mods: Record<Ability, number>, profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[], proficiencyBonus: number, weaponAbilityOverride?: Ability): DerivedEquipment;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computeAppliedBonuses,
|
|
3
|
+
computeSlotsAndAttacks,
|
|
4
|
+
emptyAppliedBonuses
|
|
5
|
+
} from "../chunk-QQ5W2AZP.js";
|
|
6
|
+
import "../chunk-UC4FE5X3.js";
|
|
7
|
+
import "../chunk-LWFTHJIE.js";
|
|
8
|
+
import "../chunk-DNAJRMNN.js";
|
|
9
|
+
import "../chunk-DC74TZNA.js";
|
|
10
|
+
import "../chunk-3TRGRSCH.js";
|
|
11
|
+
export {
|
|
12
|
+
computeAppliedBonuses,
|
|
13
|
+
computeSlotsAndAttacks,
|
|
14
|
+
emptyAppliedBonuses
|
|
15
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { SenseType } from "@archivist-gg/dnd5e/types/feature-effect";
|
|
2
|
+
import type { Ability } from "@archivist-gg/dnd5e";
|
|
3
|
+
import type { ResolvedFeature, RollModifierEntry } from "./pc.types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Aggregated passive feature effects (effects-application engine).
|
|
6
|
+
* One pure scan over resolved.features[].feature.effects[]. Merge semantics
|
|
7
|
+
* mirror pc.conditions mergePartial: numbers add, each sense range takes max,
|
|
8
|
+
* lists union case-insensitively. apply-condition and damage-bonus are action/attack
|
|
9
|
+
* time and intentionally not aggregated; `while`-gated immune-condition
|
|
10
|
+
* entries are skipped entirely (conditional effects are a named deferral).
|
|
11
|
+
*/
|
|
12
|
+
export interface FeatureEffectTotals {
|
|
13
|
+
initiative_bonus: number;
|
|
14
|
+
hp_per_level_bonus: number;
|
|
15
|
+
speed_walk_bonus: number;
|
|
16
|
+
/**
|
|
17
|
+
* Absolute walk-speed FLOOR from `speed-bonus` effects with `set:true` (e.g.
|
|
18
|
+
* a "base speed becomes 60" feature). Max across all set effects; 0 = none.
|
|
19
|
+
* recalc applies it as Math.max(set, race + additive bonuses) so it never
|
|
20
|
+
* lowers an already-higher speed and is independent of the additive bonus.
|
|
21
|
+
*/
|
|
22
|
+
speed_walk_set: number;
|
|
23
|
+
/** Max range per sense type granted by effects; 0 = none for that type. */
|
|
24
|
+
senses: Record<SenseType, number>;
|
|
25
|
+
/** One term per ac-bonus effect, labeled with the owning feature's name. */
|
|
26
|
+
ac_terms: {
|
|
27
|
+
value: number;
|
|
28
|
+
requires_armor: boolean;
|
|
29
|
+
label: string;
|
|
30
|
+
}[];
|
|
31
|
+
resistances: string[];
|
|
32
|
+
condition_immunities: string[];
|
|
33
|
+
/**
|
|
34
|
+
* skills are kebab-case lowercase slugs (matching skill slugs). armor/weapons
|
|
35
|
+
* are lowercase CATEGORY words ("heavy"/"shield", "simple"/"martial") — the
|
|
36
|
+
* same form class/race/feat grants use; recalc folds them into the matcher's
|
|
37
|
+
* `.categories` bucket, NOT `.specific` (which is per-item slugs). tools/languages
|
|
38
|
+
* keep their display spelling; saves are canonical ability keys.
|
|
39
|
+
*/
|
|
40
|
+
proficiencies: {
|
|
41
|
+
skills: string[];
|
|
42
|
+
tools: string[];
|
|
43
|
+
languages: string[];
|
|
44
|
+
saves: Ability[];
|
|
45
|
+
armor: string[];
|
|
46
|
+
weapons: string[];
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* v1 global melee-attack ability override (Hexblade "Lies", etc.). The first
|
|
50
|
+
* `weapon-ability` effect with a concrete ability (not `"spellcasting"`) wins;
|
|
51
|
+
* `"spellcasting"` is resolved against the caster ability in recalc. `weapons`
|
|
52
|
+
* scope is parsed but ignored here (global override). null = no override.
|
|
53
|
+
*/
|
|
54
|
+
weaponAbility: Ability | null;
|
|
55
|
+
/**
|
|
56
|
+
* Order-preserving list of structured advantage/disadvantage entries from
|
|
57
|
+
* `roll-modifier` effects. Pass-through (no dedupe/merge); each entry is
|
|
58
|
+
* labeled with the owning feature's name.
|
|
59
|
+
*/
|
|
60
|
+
rollModifiers: RollModifierEntry[];
|
|
61
|
+
/**
|
|
62
|
+
* Lowest weapon-attack crit threshold (natural roll that scores a critical
|
|
63
|
+
* hit) granted by `crit-range` effects. Folds via Math.min from init 20, so
|
|
64
|
+
* 20 = no expansion. spell-only (`applies_to:"spell"`) entries do NOT lower
|
|
65
|
+
* it. recalc maps this onto each AttackRow as `critRange` only when < 20.
|
|
66
|
+
*/
|
|
67
|
+
critRange: number;
|
|
68
|
+
/**
|
|
69
|
+
* Max extra attacks per Attack action granted by `extra-attack` effects.
|
|
70
|
+
* Non-stacking (D&D Extra Attack features don't stack): folds via Math.max
|
|
71
|
+
* from init 0, so 0 = no extra attacks. recalc maps this onto
|
|
72
|
+
* DerivedStats.attacksPerAction as `1 + extraAttack`.
|
|
73
|
+
*/
|
|
74
|
+
extraAttack: number;
|
|
75
|
+
/**
|
|
76
|
+
* Order-preserving display-only captions surfaced from `reroll-damage` and
|
|
77
|
+
* `attack-rule` effects (e.g. "Reroll 2s", "No disadvantage firing in melee").
|
|
78
|
+
* recalc post-applies this list onto each AttackRow as `attackNotes` only when
|
|
79
|
+
* non-empty, so untouched attack rows keep `attackNotes: undefined`.
|
|
80
|
+
*/
|
|
81
|
+
attackNotes: string[];
|
|
82
|
+
}
|
|
83
|
+
export declare function emptyFeatureEffectTotals(): FeatureEffectTotals;
|
|
84
|
+
/**
|
|
85
|
+
* Optional fold inputs. `activeBuffs` is the set of currently-toggled buff
|
|
86
|
+
* ids/slugs (from Character.state.active_buffs + selected pool boons). An
|
|
87
|
+
* `activatable` feature's effects fold ONLY while its id is in this set; a buff
|
|
88
|
+
* is OFF by default, so callers passing no opts see activatable features fold to
|
|
89
|
+
* nothing (correct — a buff is off until toggled). Non-activatable features fold
|
|
90
|
+
* unconditionally regardless of opts.
|
|
91
|
+
*/
|
|
92
|
+
export interface FeatureEffectsOpts {
|
|
93
|
+
activeBuffs?: Set<string>;
|
|
94
|
+
}
|
|
95
|
+
export declare function computeFeatureEffects(features: ResolvedFeature[], opts?: FeatureEffectsOpts): FeatureEffectTotals;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EntityRegistry } from "@archivist-gg/core";
|
|
2
|
+
import type { FormulaContext } from "@archivist-gg/dnd5e/types/formula-context";
|
|
3
|
+
import type { DerivedStats, ResolvedCharacter } from "./pc.types.js";
|
|
4
|
+
export declare function buildFormulaContext(resolved: ResolvedCharacter, derived: DerivedStats, registry: EntityRegistry): FormulaContext;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/pc/pc.formula-context.ts
|
|
2
|
+
function buildFormulaContext(resolved, derived, registry) {
|
|
3
|
+
return {
|
|
4
|
+
abilities: resolved.definition.abilities,
|
|
5
|
+
proficiencyBonus: derived.proficiencyBonus,
|
|
6
|
+
compendium: registry
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
buildFormulaContext
|
|
11
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
characterSchema
|
|
3
|
+
} from "../chunk-ZLG6FQFB.js";
|
|
4
|
+
import "../chunk-TZK36BU7.js";
|
|
5
|
+
|
|
6
|
+
// src/pc/pc.parser.ts
|
|
7
|
+
import * as yaml from "js-yaml";
|
|
8
|
+
function parsePC(source) {
|
|
9
|
+
let raw;
|
|
10
|
+
try {
|
|
11
|
+
raw = yaml.load(source);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14
|
+
return { success: false, error: `YAML parse error: ${msg}` };
|
|
15
|
+
}
|
|
16
|
+
if (!raw || typeof raw !== "object") {
|
|
17
|
+
return { success: false, error: "Invalid YAML: expected an object" };
|
|
18
|
+
}
|
|
19
|
+
const result = characterSchema.safeParse(raw);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
const issue = result.error.issues[0];
|
|
22
|
+
const path = issue.path.length ? issue.path.join(".") : "(root)";
|
|
23
|
+
return { success: false, error: `${path}: ${issue.message}` };
|
|
24
|
+
}
|
|
25
|
+
const data = result.data;
|
|
26
|
+
const legacyState = data.state;
|
|
27
|
+
const legacyCurrency = legacyState.currency;
|
|
28
|
+
if (legacyCurrency && !data.currency) {
|
|
29
|
+
data.currency = legacyCurrency;
|
|
30
|
+
}
|
|
31
|
+
if (legacyCurrency) {
|
|
32
|
+
delete legacyState.currency;
|
|
33
|
+
}
|
|
34
|
+
if (legacyState.attuned_items) {
|
|
35
|
+
delete legacyState.attuned_items;
|
|
36
|
+
}
|
|
37
|
+
return { success: true, data };
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
parsePC
|
|
41
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RegisteredEntity } from "@archivist-gg/core";
|
|
2
|
+
import type { ResolvedCharacter, ResolvedClass, ResolvedPool } from "./pc.types.js";
|
|
3
|
+
import type { SelectionPool } from "@archivist-gg/dnd5e/types/selection-pool";
|
|
4
|
+
import type { OptionalFeatureEntity } from "@archivist-gg/dnd5e/types/optional-feature.types";
|
|
5
|
+
/** Structural subset of EntityRegistry used here (lets tests pass a fake). */
|
|
6
|
+
export interface PoolRegistry {
|
|
7
|
+
search(query: string, entityType: string, limit: number): RegisteredEntity[];
|
|
8
|
+
getByTypeAndSlug(entityType: string, slug: string): RegisteredEntity | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function levelPrereqMax(d: OptionalFeatureEntity): number;
|
|
11
|
+
export declare function resolvePool(rc: ResolvedClass, classIndex: number, pool: SelectionPool, registry: PoolRegistry): ResolvedPool;
|
|
12
|
+
export declare function resolveAllPools(resolved: ResolvedCharacter, registry: PoolRegistry): ResolvedPool[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
levelPrereqMax,
|
|
3
|
+
resolveAllPools,
|
|
4
|
+
resolvePool
|
|
5
|
+
} from "../chunk-6PXE7T7C.js";
|
|
6
|
+
import "../chunk-5XUXXAQJ.js";
|
|
7
|
+
import "../chunk-TJCNX6UZ.js";
|
|
8
|
+
import "../chunk-BH6AMZVY.js";
|
|
9
|
+
import "../chunk-JEYQU3JT.js";
|
|
10
|
+
import "../chunk-WP2CX2JO.js";
|
|
11
|
+
export {
|
|
12
|
+
levelPrereqMax,
|
|
13
|
+
resolveAllPools,
|
|
14
|
+
resolvePool
|
|
15
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResolvedCharacter } from "./pc.types.js";
|
|
2
|
+
export interface ProficiencyAggregate {
|
|
3
|
+
armor: string[];
|
|
4
|
+
weapons: string[];
|
|
5
|
+
tools: string[];
|
|
6
|
+
languages: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function aggregateProficiencies(resolved: ResolvedCharacter): ProficiencyAggregate;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/pc/pc.proficiencies.ts
|
|
2
|
+
function aggregateProficiencies(resolved) {
|
|
3
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
4
|
+
const armor = /* @__PURE__ */ new Set();
|
|
5
|
+
const weapons = /* @__PURE__ */ new Set();
|
|
6
|
+
const tools = /* @__PURE__ */ new Set();
|
|
7
|
+
const languages = /* @__PURE__ */ new Set();
|
|
8
|
+
for (const c of resolved.classes) {
|
|
9
|
+
const prof = (_a = c.entity) == null ? void 0 : _a.proficiencies;
|
|
10
|
+
if (!prof) continue;
|
|
11
|
+
for (const a of (_b = prof.armor) != null ? _b : []) armor.add(prettyName(a));
|
|
12
|
+
if ((_c = prof.weapons) == null ? void 0 : _c.fixed) for (const w of prof.weapons.fixed) weapons.add(prettyName(w));
|
|
13
|
+
if ((_d = prof.weapons) == null ? void 0 : _d.categories) for (const w of prof.weapons.categories) weapons.add(prettyName(w));
|
|
14
|
+
if ((_e = prof.tools) == null ? void 0 : _e.fixed) for (const t of prof.tools.fixed) tools.add(prettyName(t));
|
|
15
|
+
}
|
|
16
|
+
const raceLangs = (_f = resolved.race) == null ? void 0 : _f.languages;
|
|
17
|
+
if (raceLangs == null ? void 0 : raceLangs.fixed) for (const l of raceLangs.fixed) languages.add(prettyName(l));
|
|
18
|
+
const bg = resolved.background;
|
|
19
|
+
if (bg) {
|
|
20
|
+
for (const entry of (_g = bg.tool_proficiencies) != null ? _g : []) {
|
|
21
|
+
if (entry.kind === "fixed") for (const t of entry.items) tools.add(prettyName(t));
|
|
22
|
+
}
|
|
23
|
+
for (const entry of (_h = bg.language_proficiencies) != null ? _h : []) {
|
|
24
|
+
if (entry.kind === "fixed") for (const l of entry.languages) languages.add(prettyName(l));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const f of resolved.feats) {
|
|
28
|
+
const grants = f.proficiencies;
|
|
29
|
+
if (!grants) continue;
|
|
30
|
+
for (const a of (_i = grants.armor) != null ? _i : []) armor.add(prettyName(a));
|
|
31
|
+
for (const w of (_j = grants.weapons) != null ? _j : []) weapons.add(prettyName(w));
|
|
32
|
+
for (const t of (_k = grants.tools) != null ? _k : []) tools.add(prettyName(t));
|
|
33
|
+
for (const l of (_l = grants.languages) != null ? _l : []) languages.add(prettyName(l));
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
armor: [...armor].sort(),
|
|
37
|
+
weapons: [...weapons].sort(),
|
|
38
|
+
tools: [...tools].sort(),
|
|
39
|
+
languages: [...languages].sort()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function prettyName(slug) {
|
|
43
|
+
return slug.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
aggregateProficiencies
|
|
47
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ArmorEntity } from "@archivist-gg/dnd5e/armor/armor.types";
|
|
2
|
+
import type { WeaponEntity } from "@archivist-gg/dnd5e/weapon/weapon.types";
|
|
3
|
+
import type { ProficiencySet } from "./pc.types.js";
|
|
4
|
+
interface ProficienciesForQuery {
|
|
5
|
+
armor: ProficiencySet;
|
|
6
|
+
weapons: ProficiencySet;
|
|
7
|
+
tools: ProficiencySet;
|
|
8
|
+
}
|
|
9
|
+
export declare function isProficientWithWeapon(weapon: WeaponEntity, profs: ProficienciesForQuery): boolean;
|
|
10
|
+
export declare function isProficientWithArmor(armor: ArmorEntity, profs: ProficienciesForQuery): boolean;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/pc/pc.proficiency-query.ts
|
|
2
|
+
function isProficientWithWeapon(weapon, profs) {
|
|
3
|
+
if (profs.weapons.specific.includes(weapon.slug)) return true;
|
|
4
|
+
const baseCategory = weapon.category.split("-")[0];
|
|
5
|
+
return profs.weapons.categories.includes(baseCategory);
|
|
6
|
+
}
|
|
7
|
+
function isProficientWithArmor(armor, profs) {
|
|
8
|
+
if (profs.armor.specific.includes(armor.slug)) return true;
|
|
9
|
+
if (profs.armor.categories.includes(armor.category)) return true;
|
|
10
|
+
if (armor.category === "light" && (profs.armor.categories.includes("medium") || profs.armor.categories.includes("heavy"))) return true;
|
|
11
|
+
if (armor.category === "medium" && profs.armor.categories.includes("heavy")) return true;
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
isProficientWithArmor,
|
|
16
|
+
isProficientWithWeapon
|
|
17
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { Ability } from "@archivist-gg/dnd5e";
|
|
2
|
+
import type { FeatEntity } from "@archivist-gg/dnd5e/feat/feat.types";
|
|
3
|
+
import type { RaceEntity } from "@archivist-gg/dnd5e/race/race.types";
|
|
4
|
+
import type { EntityRegistry } from "@archivist-gg/core";
|
|
5
|
+
import type { ACTerm, DerivedStats, ProficiencySet, ResolvedCharacter, ResolvedClass, CharacterOverrides } from "./pc.types.js";
|
|
6
|
+
/**
|
|
7
|
+
* PHB "fixed average" value per hit die (per level beyond first). Called
|
|
8
|
+
* "average" in the PHB but actually ceil((die + 1) / 2); equivalent to
|
|
9
|
+
* Math.floor(die / 2) + 1 for even dice.
|
|
10
|
+
*
|
|
11
|
+
* d6 → 4, d8 → 5, d10 → 6, d12 → 7.
|
|
12
|
+
*/
|
|
13
|
+
export declare function phbAverageForDie(hitDieStr: string): number;
|
|
14
|
+
/** Extracts the integer size from "d8" / "d10" / 8 / 10. */
|
|
15
|
+
export declare function parseDieSize(die: string | number | undefined | null): number | null;
|
|
16
|
+
/**
|
|
17
|
+
* Flattens RaceEntity.ability_score_increases into a partial ability→bonus map.
|
|
18
|
+
* Fixed increases contribute their amount directly. Choice increases are ignored
|
|
19
|
+
* here — they're expected to come through class.choices with a specific ability
|
|
20
|
+
* selected, which computeAbilityScores handles separately.
|
|
21
|
+
*/
|
|
22
|
+
export declare function flattenRaceAsi(race: RaceEntity | null): Partial<Record<Ability, number>>;
|
|
23
|
+
/**
|
|
24
|
+
* Sums the LEGACY class-level ASI-BRANCH allocations (`choices[lvl].asi`) per
|
|
25
|
+
* ability across every class. This is the path taken when an L4/L8-style
|
|
26
|
+
* "Ability Score Increase or Feat" decision resolves to the plain +2 ASI branch
|
|
27
|
+
* rather than a feat. Shared by both `computeAbilityScores`' fold and
|
|
28
|
+
* `abilityBonusBreakdown`'s `class` bucket so the two reads can never drift.
|
|
29
|
+
*
|
|
30
|
+
* Disjoint from chosen-feat ability-points (`choices[lvl]["feat:<id>"]`) and from
|
|
31
|
+
* origin ability-points — no source double-counts.
|
|
32
|
+
*/
|
|
33
|
+
export declare function collectClassAsiBranch(resolved: ResolvedCharacter): Partial<Record<Ability, number>>;
|
|
34
|
+
/** Per-ability bonus provenance for the builder's obelisk captions:
|
|
35
|
+
* species = fixed race ASI + subrace fixed ASI + race ability-points choices;
|
|
36
|
+
* background = background ability-points choices;
|
|
37
|
+
* class = legacy class ASI-BRANCH allocations (the L4 asi-or-feat → asi path);
|
|
38
|
+
* feat = class chosen-feat ability-points (the L4 asi-or-feat → feat path) +
|
|
39
|
+
* flat feat ability_bonuses (e.g. Athlete +1 STR). All already fold into
|
|
40
|
+
* computeAbilityScores totals, so the caption must account for them or a
|
|
41
|
+
* tile reads higher than the named sources explain (smoke r1/r5c). */
|
|
42
|
+
export declare function abilityBonusBreakdown(resolved: ResolvedCharacter): Record<Ability, {
|
|
43
|
+
species: number;
|
|
44
|
+
background: number;
|
|
45
|
+
class: number;
|
|
46
|
+
feat: number;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* PC-oriented multiclass HP.
|
|
50
|
+
* - First class's first level: max(hit_die) + conMod.
|
|
51
|
+
* - Every subsequent level (in any class): phbAverageForDie(thatLevel'sClass) + conMod.
|
|
52
|
+
* CON mod contributes once per total level.
|
|
53
|
+
*/
|
|
54
|
+
export declare function multiclassMaxHP(classes: ResolvedClass[], conMod: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* Default AC = 10 + DEX mod. If any class's features include an
|
|
57
|
+
* "Unarmored Defense"–style feature with a structured flag, applies the
|
|
58
|
+
* variant (Monk: +WIS; Barbarian: +CON). Falls back to feature-name
|
|
59
|
+
* regex matching with a warning pushed onto `warnings`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function unarmoredAC(resolved: ResolvedCharacter, mods: Record<Ability, number>, warnings: string[]): number;
|
|
62
|
+
/**
|
|
63
|
+
* Same logic as `unarmoredAC` but also returns a structured breakdown of the
|
|
64
|
+
* contributing terms (Base 10, DEX, optional class unarmored defense ability).
|
|
65
|
+
* Used by recalc to assemble a richer acBreakdown when no armor is equipped.
|
|
66
|
+
*/
|
|
67
|
+
export declare function unarmoredACBreakdown(resolved: ResolvedCharacter, mods: Record<Ability, number>, warnings: string[]): {
|
|
68
|
+
total: number;
|
|
69
|
+
terms: ACTerm[];
|
|
70
|
+
};
|
|
71
|
+
/** Initiative = DEX mod + Alert (+5 in 2014). Extendable via feat flags. */
|
|
72
|
+
export declare function initiativeBonus(dexMod: number, feats: FeatEntity[], edition: "2014" | "2024"): number;
|
|
73
|
+
/** Speed = race.speed.walk + flat bonuses from feats (e.g., Mobile +10). */
|
|
74
|
+
export declare function speedFromRace(resolved: ResolvedCharacter): number;
|
|
75
|
+
/**
|
|
76
|
+
* Folds class-level CHOSEN-FEAT ability-points into per-ability totals.
|
|
77
|
+
*
|
|
78
|
+
* When the L4-style "asi or feat" decision resolves to a feat that carries
|
|
79
|
+
* `ability-points` choices (e.g. Ability Score Improvement, the epic Boons),
|
|
80
|
+
* the picker persists the allocation under the namespaced key
|
|
81
|
+
* `choices[lvl]["feat:" + choice.id]` (the engine's `buildItem` surfaces those
|
|
82
|
+
* children; see pc.decision-engine.ts). This is disjoint from both the legacy
|
|
83
|
+
* asi-BRANCH key (`choices[lvl].asi`) and origin ability-points, so no source
|
|
84
|
+
* double-counts. The chosen feat entity is resolved from `resolved.feats`
|
|
85
|
+
* (already looked up by the resolver) — no registry needed here.
|
|
86
|
+
*
|
|
87
|
+
* Clamps defensively (per-ability max_per, then stops at the points total in
|
|
88
|
+
* ABILITY_KEYS order), mirroring collectChosenAbilityPoints.
|
|
89
|
+
*/
|
|
90
|
+
export declare function collectClassFeatAbilityPoints(resolved: ResolvedCharacter): Partial<Record<Ability, number>>;
|
|
91
|
+
/**
|
|
92
|
+
* Combines racial ASI (from race.ability_score_increases), feat ASI,
|
|
93
|
+
* class-choice ASI (from classes[i].choices[lvl].asi), chosen-feat ASI
|
|
94
|
+
* (from classes[i].choices[lvl]["feat:<id>"]), and user overrides.
|
|
95
|
+
* Overrides win; ASI sources sum unconditionally.
|
|
96
|
+
*/
|
|
97
|
+
export declare function computeAbilityScores(resolved: ResolvedCharacter, overrides: CharacterOverrides): Record<Ability, number>;
|
|
98
|
+
export declare function computeProficiencies(resolved: ResolvedCharacter): {
|
|
99
|
+
armor: ProficiencySet;
|
|
100
|
+
weapons: ProficiencySet;
|
|
101
|
+
tools: ProficiencySet;
|
|
102
|
+
languages: string[];
|
|
103
|
+
saves: Ability[];
|
|
104
|
+
};
|
|
105
|
+
export declare function recalc(resolved: ResolvedCharacter, registry?: EntityRegistry): DerivedStats;
|