@archivist-gg/dnd5e 0.3.13 → 0.3.17
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/background/background.codec.js +5 -5
- package/dist/background/background.parser.js +4 -4
- package/dist/background/background.schema.js +3 -3
- package/dist/{chunk-ZMJQUZQH.js → chunk-2JSQE3DD.js} +11 -0
- package/dist/{chunk-Q6UOHCCT.js → chunk-2UDSN6VW.js} +1 -1
- package/dist/chunk-3LWMFYKS.js +57 -0
- package/dist/{chunk-MUIU7RZ3.js → chunk-3MGQFFNE.js} +1 -1
- package/dist/{chunk-T5GZBKIQ.js → chunk-3VZZDKRA.js} +114 -27
- package/dist/{chunk-BRGLDWUP.js → chunk-5MXFW4O3.js} +7 -3
- package/dist/{chunk-RQNJXADQ.js → chunk-6EI737IO.js} +1 -1
- package/dist/{chunk-EL6QPF6I.js → chunk-7ATNGKBS.js} +1 -1
- package/dist/{chunk-XY6X2APM.js → chunk-7Q2VPKCD.js} +17 -0
- package/dist/{chunk-4SLOJXJ4.js → chunk-7QN7XSAK.js} +1 -1
- package/dist/{chunk-MC5YJ4PB.js → chunk-AZRGFUSR.js} +1 -1
- package/dist/{chunk-HJQNK3J5.js → chunk-B3DP42OM.js} +1 -4
- package/dist/{chunk-JNNNBEUH.js → chunk-DOXSFYLH.js} +7 -2
- package/dist/{chunk-X7VZY4ON.js → chunk-FANQVQ3D.js} +2 -2
- package/dist/{chunk-PX25R3DK.js → chunk-G6PBI2BU.js} +1 -1
- package/dist/chunk-HTYMW5CH.js +228 -0
- package/dist/{chunk-VDPRBUU5.js → chunk-JCMUVZIK.js} +1 -1
- package/dist/{chunk-Q5XTEYHD.js → chunk-JSM6JFZR.js} +15 -8
- package/dist/chunk-KR6JF3BF.js +14 -0
- package/dist/{chunk-J53ERF6K.js → chunk-LF5AGJA4.js} +1 -1
- package/dist/{chunk-XJRNEQPD.js → chunk-MBX25B6D.js} +1 -1
- package/dist/{chunk-5KGV6TF7.js → chunk-OFCSP6MT.js} +1 -1
- package/dist/{chunk-QEO7LYTG.js → chunk-ONTGZR5T.js} +127 -71
- package/dist/{chunk-MWCCGPG3.js → chunk-OOSRUJBI.js} +3 -2
- package/dist/{chunk-LVX6TQ3R.js → chunk-PKX6TGRE.js} +2 -2
- package/dist/{chunk-QSBJ6NEM.js → chunk-PQZ4LM4Z.js} +1 -1
- package/dist/chunk-PXVNAY7T.js +84 -0
- package/dist/chunk-QH36K2PU.js +158 -0
- package/dist/{chunk-M2OWVAZG.js → chunk-QZSWN2KT.js} +1 -1
- package/dist/{chunk-6ZY3U6BQ.js → chunk-RYLXAYIQ.js} +1 -1
- package/dist/{chunk-UE6LKRXQ.js → chunk-T6QIF5XR.js} +16 -0
- package/dist/{chunk-4BZ47YJ4.js → chunk-TULQ4FFX.js} +32 -11
- package/dist/{chunk-PLOSP4XQ.js → chunk-UUBJCNQU.js} +11 -2
- package/dist/{chunk-DPM6V7YX.js → chunk-VRV3NNTA.js} +1 -1
- package/dist/{chunk-R2V5LN3I.js → chunk-Y5VVP73C.js} +1 -1
- package/dist/{chunk-FPGXFD2M.js → chunk-YD2VAHA6.js} +2 -2
- package/dist/{chunk-G7ED5H2G.js → chunk-YKL6SHRJ.js} +1 -1
- package/dist/class/class.codec.js +6 -6
- package/dist/class/class.parser.js +5 -5
- package/dist/class/class.schema.d.ts +8 -0
- package/dist/class/class.schema.js +4 -4
- package/dist/class/class.standard-array.d.ts +16 -0
- package/dist/class/class.standard-array.js +20 -0
- package/dist/class/class.types.d.ts +3 -0
- package/dist/dnd/amount-text.d.ts +38 -0
- package/dist/dnd/amount-text.js +13 -0
- package/dist/dnd/resource-words.d.ts +4 -0
- package/dist/dnd/resource-words.js +30 -0
- package/dist/feat/feat.codec.js +5 -5
- package/dist/feat/feat.parser.js +4 -4
- package/dist/feat/feat.schema.d.ts +25 -0
- package/dist/feat/feat.schema.js +3 -3
- package/dist/index.js +332 -70
- package/dist/monster/monster.parser.js +5 -5
- package/dist/monster/monster.schema.js +4 -4
- package/dist/optional-feature/optional-feature.codec.js +5 -4
- package/dist/optional-feature/optional-feature.parser.js +4 -3
- package/dist/optional-feature/optional-feature.schema.d.ts +26 -0
- package/dist/optional-feature/optional-feature.schema.js +3 -2
- package/dist/pc/pc.additional-spells.js +2 -2
- package/dist/pc/pc.amount-bindings.d.ts +32 -0
- package/dist/pc/pc.amount-bindings.js +23 -0
- package/dist/pc/pc.decision-engine.d.ts +3 -0
- package/dist/pc/pc.decision-engine.js +14 -13
- package/dist/pc/pc.entry-overrides.js +3 -3
- package/dist/pc/pc.equipment.js +6 -5
- package/dist/pc/pc.feature-effects.d.ts +12 -0
- package/dist/pc/pc.feature-effects.js +1 -1
- package/dist/pc/pc.infusions.d.ts +9 -1
- package/dist/pc/pc.infusions.js +3 -3
- package/dist/pc/pc.member-choices.d.ts +90 -0
- package/dist/pc/pc.member-choices.js +32 -0
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.d.ts +7 -0
- package/dist/pc/pc.pools.js +5 -3
- package/dist/pc/pc.proficiencies.js +13 -12
- package/dist/pc/pc.proficiency-query.js +6 -0
- package/dist/pc/pc.recalc.js +75 -58
- package/dist/pc/pc.resolver.d.ts +2 -1
- package/dist/pc/pc.resolver.js +13 -12
- package/dist/pc/pc.rest.js +4 -4
- package/dist/pc/pc.schema.d.ts +29 -2
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.types.d.ts +45 -2
- package/dist/pc/pc.weapon-grant.d.ts +15 -0
- package/dist/pc/pool-layout.d.ts +3 -9
- package/dist/pc/pool-layout.js +1 -3
- package/dist/pc/resource-equivalents.d.ts +44 -0
- package/dist/pc/spell-source.js +4 -9
- package/dist/race/race.codec.js +6 -6
- package/dist/race/race.parser.js +5 -5
- package/dist/race/race.schema.js +4 -4
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/feature-effect-schema.d.ts +25 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.js +3 -3
- package/dist/spell/spell.codec.js +2 -2
- package/dist/spell/spell.parser.d.ts +6 -1
- package/dist/spell/spell.parser.js +5 -3
- package/dist/spell/spell.types.d.ts +10 -0
- package/dist/subclass/subclass.codec.js +6 -6
- package/dist/subclass/subclass.parser.js +5 -5
- package/dist/subclass/subclass.schema.js +4 -4
- package/dist/types/choice.d.ts +5 -0
- package/dist/types/feature-effect.d.ts +6 -0
- package/dist/types/optional-feature.types.d.ts +5 -0
- package/dist/types/selection-pool.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
optionalFeatureCodec
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-G6PBI2BU.js";
|
|
4
|
+
import "../chunk-PQZ4LM4Z.js";
|
|
5
|
+
import "../chunk-DOXSFYLH.js";
|
|
6
6
|
import "../chunk-WYGD2UGN.js";
|
|
7
7
|
import "../chunk-ZJXSXVFP.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-5MXFW4O3.js";
|
|
9
|
+
import "../chunk-2JSQE3DD.js";
|
|
9
10
|
import "../chunk-UA5KS2PL.js";
|
|
10
11
|
export {
|
|
11
12
|
optionalFeatureCodec
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseOptionalFeature
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-PQZ4LM4Z.js";
|
|
4
|
+
import "../chunk-DOXSFYLH.js";
|
|
5
5
|
import "../chunk-WYGD2UGN.js";
|
|
6
6
|
import "../chunk-ZJXSXVFP.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-5MXFW4O3.js";
|
|
8
|
+
import "../chunk-2JSQE3DD.js";
|
|
8
9
|
import "../chunk-UA5KS2PL.js";
|
|
9
10
|
export {
|
|
10
11
|
parseOptionalFeature
|
|
@@ -183,6 +183,31 @@ export declare const optionalFeatureEntitySchema: z.ZodObject<{
|
|
|
183
183
|
minimum: z.ZodOptional<z.ZodNumber>;
|
|
184
184
|
condition: z.ZodOptional<z.ZodString>;
|
|
185
185
|
subject: z.ZodOptional<z.ZodString>;
|
|
186
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
187
|
+
kind: z.ZodLiteral<"save-bonus">;
|
|
188
|
+
ability: z.ZodEnum<{
|
|
189
|
+
str: "str";
|
|
190
|
+
dex: "dex";
|
|
191
|
+
con: "con";
|
|
192
|
+
int: "int";
|
|
193
|
+
wis: "wis";
|
|
194
|
+
cha: "cha";
|
|
195
|
+
}>;
|
|
196
|
+
minimum: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
saves: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
198
|
+
str: "str";
|
|
199
|
+
dex: "dex";
|
|
200
|
+
con: "con";
|
|
201
|
+
int: "int";
|
|
202
|
+
wis: "wis";
|
|
203
|
+
cha: "cha";
|
|
204
|
+
}>>>;
|
|
205
|
+
inactive_while: z.ZodOptional<z.ZodEnum<{
|
|
206
|
+
incapacitated: "incapacitated";
|
|
207
|
+
unconscious: "unconscious";
|
|
208
|
+
}>>;
|
|
209
|
+
condition: z.ZodOptional<z.ZodString>;
|
|
210
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
186
211
|
}, z.core.$strip>, z.ZodObject<{
|
|
187
212
|
kind: z.ZodLiteral<"half-proficiency">;
|
|
188
213
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -689,6 +714,7 @@ export declare const optionalFeatureEntitySchema: z.ZodObject<{
|
|
|
689
714
|
}, z.core.$strict>;
|
|
690
715
|
}, z.core.$strict>>>;
|
|
691
716
|
}, z.core.$strict>>;
|
|
717
|
+
choices: z.ZodOptional<z.ZodArray<z.ZodType<import("../index.js").Choice, unknown, z.core.$ZodTypeInternals<import("../index.js").Choice, unknown>>>>;
|
|
692
718
|
}, z.core.$strip>;
|
|
693
719
|
export type OptionalFeatureSchemaInput = z.input<typeof optionalFeatureEntitySchema>;
|
|
694
720
|
export type OptionalFeatureSchemaOutput = z.output<typeof optionalFeatureEntitySchema>;
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
infuseBlockSchema,
|
|
3
3
|
optionRowSchema,
|
|
4
4
|
optionalFeatureEntitySchema
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-DOXSFYLH.js";
|
|
6
6
|
import "../chunk-WYGD2UGN.js";
|
|
7
7
|
import "../chunk-ZJXSXVFP.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-5MXFW4O3.js";
|
|
9
|
+
import "../chunk-2JSQE3DD.js";
|
|
9
10
|
import "../chunk-UA5KS2PL.js";
|
|
10
11
|
export {
|
|
11
12
|
infuseBlockSchema,
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
prefixOf,
|
|
6
6
|
raceIsUngated,
|
|
7
7
|
resolveSpellByName
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-VRV3NNTA.js";
|
|
9
9
|
import "../chunk-PVCEA4HZ.js";
|
|
10
10
|
import "../chunk-LVQLWRCU.js";
|
|
11
11
|
import "../chunk-ZCTUYGNV.js";
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-7Q2VPKCD.js";
|
|
13
13
|
import "../chunk-ZDAEGJH4.js";
|
|
14
14
|
import "../chunk-WELIKLZF.js";
|
|
15
15
|
import "../chunk-UA5KS2PL.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D2b-A · the numbers an amount resolves against (design §1.2 A). The modifier and the save DC are those of the class
|
|
3
|
+
* that OWNS the feature or grants the spell (multiclass: the granting class, user ruling 2026-09-27).
|
|
4
|
+
*/
|
|
5
|
+
import type { Ability } from "@archivist-gg/dnd5e/types/choice";
|
|
6
|
+
import type { Spell } from "@archivist-gg/dnd5e/spell/spell.types";
|
|
7
|
+
import type { AmountBindings } from "@archivist-gg/dnd5e/dnd/amount-text";
|
|
8
|
+
import type { DerivedStats, FeatureSource, ResolvedCharacter, ResolvedSpell } from "./pc.types.js";
|
|
9
|
+
/** The derived fields the bindings read (recalc builds them before its return; the sheet passes `ctx.derived`). */
|
|
10
|
+
export type AmountDerived = Pick<DerivedStats, "proficiencyBonus" | "mods" | "spellcastingClasses"> & Partial<Pick<DerivedStats, "abilitySpellcasting">>;
|
|
11
|
+
/** The class slug that owns `source`: a class by its slug, a subclass by the class that holds it, a feat through the
|
|
12
|
+
* slot it was taken at (`via`), a pool member through its pool's class. Null for race, background and campaign. */
|
|
13
|
+
export declare function ownerClassSlug(source: FeatureSource | undefined, resolved: Pick<ResolvedCharacter, "classes">): string | null;
|
|
14
|
+
/** The bindings an amount owned by `owner` resolves against: `class_level` is the OWNING class's level (the total level
|
|
15
|
+
* for a race, background or unowned source), `spell_mod` / `spell_dc` come from that class's spellcasting row, else
|
|
16
|
+
* the first caster's, else they stay unbound (the amount prints its words or a label). */
|
|
17
|
+
export declare function amountBindingsFor(owner: FeatureSource | undefined, resolved: Pick<ResolvedCharacter, "classes" | "totalLevel">, derived: AmountDerived): AmountBindings;
|
|
18
|
+
/** How a spell is cast: its ability, save DC and attack bonus. A grant that carries its OWN ability (a feat's chosen
|
|
19
|
+
* ability, a race grant, a class-less row) reads `abilitySpellcasting`; every other spell reads its class's row, else
|
|
20
|
+
* the first caster's. The one lookup the Spells tab's DC, attack and effect cells share. */
|
|
21
|
+
export declare function spellcastingFor(spell: Pick<ResolvedSpell, "source" | "classSlug" | "ability">, derived: AmountDerived): {
|
|
22
|
+
ability: Ability;
|
|
23
|
+
saveDC: number;
|
|
24
|
+
attackBonus: number;
|
|
25
|
+
} | null;
|
|
26
|
+
/** The bindings a spell's effect resolves against: its caster's modifier and save DC (see {@link spellcastingFor}). */
|
|
27
|
+
export declare function spellAmountBindings(spell: Pick<ResolvedSpell, "source" | "classSlug" | "ability">, resolved: Pick<ResolvedCharacter, "classes" | "totalLevel">, derived: AmountDerived): AmountBindings;
|
|
28
|
+
/** What a spell adds to its base roll ONCE, in token form: `{spell_mod}` when its text reads "<the base roll> plus (or
|
|
29
|
+
* +) your spellcasting (ability) modifier" (35 vault notes: Healing Word, Cure Wounds, Spiritual Weapon, ...), else
|
|
30
|
+
* null. Read from the note's own words at read time; the roll must be the one the phrase follows, so a spell whose
|
|
31
|
+
* modifier rides a different roll (a heal beside a damage roll) adds nothing. */
|
|
32
|
+
export declare function spellRollBonus(spell: Pick<Spell, "damage_roll" | "description">): string | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
amountBindingsFor,
|
|
3
|
+
ownerClassSlug,
|
|
4
|
+
spellAmountBindings,
|
|
5
|
+
spellRollBonus,
|
|
6
|
+
spellcastingFor
|
|
7
|
+
} from "../chunk-PXVNAY7T.js";
|
|
8
|
+
import "../chunk-KR6JF3BF.js";
|
|
9
|
+
import "../chunk-KSTV7J2U.js";
|
|
10
|
+
import "../chunk-DPUJDOKV.js";
|
|
11
|
+
import "../chunk-IUAAXXNO.js";
|
|
12
|
+
import "../chunk-LVQLWRCU.js";
|
|
13
|
+
import "../chunk-EVMUJYUD.js";
|
|
14
|
+
import "../chunk-VTTA2ALZ.js";
|
|
15
|
+
import "../chunk-PDJSUH24.js";
|
|
16
|
+
import "../chunk-WELIKLZF.js";
|
|
17
|
+
export {
|
|
18
|
+
amountBindingsFor,
|
|
19
|
+
ownerClassSlug,
|
|
20
|
+
spellAmountBindings,
|
|
21
|
+
spellRollBonus,
|
|
22
|
+
spellcastingFor
|
|
23
|
+
};
|
|
@@ -101,6 +101,9 @@ export interface DecisionItem {
|
|
|
101
101
|
* status to "partial".
|
|
102
102
|
*/
|
|
103
103
|
children?: DecisionItem[];
|
|
104
|
+
/** D2b-A (design §2.2 step 7): on a child of a pool item, the name of the member the choice belongs to ("Lessons of the
|
|
105
|
+
* First Ones"), so the strip reads "Lessons of the First Ones · Origin feat". Absent everywhere else. */
|
|
106
|
+
parentLabel?: string;
|
|
104
107
|
}
|
|
105
108
|
export interface DecisionLedger {
|
|
106
109
|
classes: Array<{
|
|
@@ -5,35 +5,36 @@ import {
|
|
|
5
5
|
collectChosenAbilityPoints,
|
|
6
6
|
collectChosenProficiencies,
|
|
7
7
|
computeEffectiveProficiencies
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-ONTGZR5T.js";
|
|
9
9
|
import "../chunk-2LULMQTF.js";
|
|
10
10
|
import "../chunk-H5PTKYXL.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-DPUJDOKV.js";
|
|
13
|
-
import "../chunk-4BZ47YJ4.js";
|
|
11
|
+
import "../chunk-TULQ4FFX.js";
|
|
14
12
|
import "../chunk-TOM66P2P.js";
|
|
15
13
|
import "../chunk-KU3YLF6D.js";
|
|
14
|
+
import "../chunk-HTYMW5CH.js";
|
|
15
|
+
import "../chunk-KSTV7J2U.js";
|
|
16
|
+
import "../chunk-DPUJDOKV.js";
|
|
17
|
+
import "../chunk-LBEXLN6I.js";
|
|
16
18
|
import "../chunk-RLGQ5PZZ.js";
|
|
17
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-3VZZDKRA.js";
|
|
18
20
|
import "../chunk-W6GC6OKK.js";
|
|
19
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-B3DP42OM.js";
|
|
20
22
|
import "../chunk-IUAAXXNO.js";
|
|
21
23
|
import "../chunk-YHYTW5QA.js";
|
|
22
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-VRV3NNTA.js";
|
|
23
25
|
import "../chunk-PVCEA4HZ.js";
|
|
24
|
-
import "../chunk-LBEXLN6I.js";
|
|
25
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
26
26
|
import "../chunk-IHE6KVC3.js";
|
|
27
27
|
import "../chunk-LHZXYFBU.js";
|
|
28
|
+
import "../chunk-YBLDE5CG.js";
|
|
29
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
28
30
|
import "../chunk-LVQLWRCU.js";
|
|
29
31
|
import "../chunk-CM5CWO4K.js";
|
|
32
|
+
import "../chunk-EVMUJYUD.js";
|
|
33
|
+
import "../chunk-VTTA2ALZ.js";
|
|
30
34
|
import {
|
|
31
35
|
wikilinkTailSlug
|
|
32
36
|
} from "../chunk-ZCTUYGNV.js";
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-EVMUJYUD.js";
|
|
35
|
-
import "../chunk-VTTA2ALZ.js";
|
|
36
|
-
import "../chunk-XY6X2APM.js";
|
|
37
|
+
import "../chunk-7Q2VPKCD.js";
|
|
37
38
|
import "../chunk-ZDAEGJH4.js";
|
|
38
39
|
import "../chunk-3TM34RSJ.js";
|
|
39
40
|
import "../chunk-PDJSUH24.js";
|
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
isWeaponLikeEntry,
|
|
12
12
|
itemChargesMax,
|
|
13
13
|
scrollSpellCost
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-3VZZDKRA.js";
|
|
15
15
|
import "../chunk-W6GC6OKK.js";
|
|
16
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-B3DP42OM.js";
|
|
17
17
|
import "../chunk-IUAAXXNO.js";
|
|
18
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
19
18
|
import "../chunk-IHE6KVC3.js";
|
|
20
19
|
import "../chunk-LHZXYFBU.js";
|
|
20
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
21
21
|
import "../chunk-LVQLWRCU.js";
|
|
22
22
|
import "../chunk-CM5CWO4K.js";
|
|
23
23
|
import "../chunk-ZCTUYGNV.js";
|
package/dist/pc/pc.equipment.js
CHANGED
|
@@ -4,19 +4,20 @@ import {
|
|
|
4
4
|
computeSlotsAndAttacks,
|
|
5
5
|
emptyAppliedBonuses,
|
|
6
6
|
isWeaponSlugProficient
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-JSM6JFZR.js";
|
|
8
|
+
import "../chunk-3LWMFYKS.js";
|
|
8
9
|
import "../chunk-YDGMBMYI.js";
|
|
10
|
+
import "../chunk-EJP263OP.js";
|
|
9
11
|
import "../chunk-RLGQ5PZZ.js";
|
|
10
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-3VZZDKRA.js";
|
|
11
13
|
import "../chunk-W6GC6OKK.js";
|
|
12
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-B3DP42OM.js";
|
|
13
15
|
import "../chunk-IUAAXXNO.js";
|
|
14
|
-
import "../chunk-EJP263OP.js";
|
|
15
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
16
16
|
import "../chunk-IHE6KVC3.js";
|
|
17
17
|
import "../chunk-HHBD4SQ6.js";
|
|
18
18
|
import "../chunk-A54HHCWW.js";
|
|
19
19
|
import "../chunk-LHZXYFBU.js";
|
|
20
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
20
21
|
import "../chunk-LVQLWRCU.js";
|
|
21
22
|
import "../chunk-CM5CWO4K.js";
|
|
22
23
|
import "../chunk-ZCTUYGNV.js";
|
|
@@ -34,6 +34,15 @@ export interface FeatureEffectTotals {
|
|
|
34
34
|
minimum: number;
|
|
35
35
|
label: string;
|
|
36
36
|
}[];
|
|
37
|
+
/** SL (spec §11.2): ability-based numeric SAVE bonuses (Aura of Protection), resolved in recalc against final scores and
|
|
38
|
+
* the character's conditions. Empty `saves` = every save; recalc keeps one term per `label`. */
|
|
39
|
+
save_bonus_terms: {
|
|
40
|
+
saves: Ability[];
|
|
41
|
+
ability: Ability;
|
|
42
|
+
minimum: number;
|
|
43
|
+
inactiveWhile?: "incapacitated" | "unconscious";
|
|
44
|
+
label: string;
|
|
45
|
+
}[];
|
|
37
46
|
/**
|
|
38
47
|
* Half-proficiency terms (Jack of All Trades, Remarkable Athlete). Resolved in recalc against the
|
|
39
48
|
* proficiency bonus, and ONLY for a skill whose effective tri is "none" — that gate is the mechanic
|
|
@@ -226,6 +235,9 @@ export declare function emptyFeatureEffectTotals(): FeatureEffectTotals;
|
|
|
226
235
|
export interface FeatureEffectsOpts {
|
|
227
236
|
activeBuffs?: Set<string>;
|
|
228
237
|
levelFor?: (source: FeatureSource) => number;
|
|
238
|
+
/** RG: the DICE cell (`1d6`) of column `column` in the table of the class that owns `source`, at `level`; null when that
|
|
239
|
+
* table has no such dice cell. recalc passes it; a caller that passes none leaves every rider at its authored amount. */
|
|
240
|
+
tableDiceFor?: (source: FeatureSource, column: string, level: number) => string | null;
|
|
229
241
|
}
|
|
230
242
|
/** Does this feature's effects fold right now? An activatable feature folds ONLY
|
|
231
243
|
* while its id is in the active set; a buff is off until toggled. Shared by
|
|
@@ -50,7 +50,9 @@ export interface CandidateOptions {
|
|
|
50
50
|
isEntityVisible?: (e: RegisteredEntity) => boolean;
|
|
51
51
|
exclude?: readonly string[];
|
|
52
52
|
}
|
|
53
|
-
/** One option row as the pickers read it (R20): `candidates` are VISIBLE full slugs in the §5.8 order (U-A).
|
|
53
|
+
/** One option row as the pickers read it (R20): `candidates` are VISIBLE full slugs in the §5.8 order (U-A). PT (spec §4,
|
|
54
|
+
* §6.5): `type` and `rarity` (lower-case) name the row's item, read from its first candidate (else its first installed
|
|
55
|
+
* item, visible or not), a `filter` row from its filter; `charges` are that item's own; null when nothing says. */
|
|
54
56
|
export interface ResolvedOptionRow {
|
|
55
57
|
key: string;
|
|
56
58
|
name: string;
|
|
@@ -59,6 +61,12 @@ export interface ResolvedOptionRow {
|
|
|
59
61
|
arm: "item" | "variant" | "filter";
|
|
60
62
|
candidates: string[];
|
|
61
63
|
availability: "installed" | "hidden-only" | "not-installed";
|
|
64
|
+
type: string | null;
|
|
65
|
+
rarity: string | null;
|
|
66
|
+
charges: {
|
|
67
|
+
max: number;
|
|
68
|
+
recharge?: string;
|
|
69
|
+
} | null;
|
|
62
70
|
}
|
|
63
71
|
/** The per-copy picker's data for one repeatable member of a pool (spec §5.1, R20). */
|
|
64
72
|
export interface RepeatableMember {
|
package/dist/pc/pc.infusions.js
CHANGED
|
@@ -23,13 +23,13 @@ import {
|
|
|
23
23
|
scaledInfuseItem,
|
|
24
24
|
splitOne,
|
|
25
25
|
withEntryCharges
|
|
26
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-3VZZDKRA.js";
|
|
27
27
|
import "../chunk-W6GC6OKK.js";
|
|
28
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-B3DP42OM.js";
|
|
29
29
|
import "../chunk-IUAAXXNO.js";
|
|
30
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
31
30
|
import "../chunk-IHE6KVC3.js";
|
|
32
31
|
import "../chunk-LHZXYFBU.js";
|
|
32
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
33
33
|
import "../chunk-LVQLWRCU.js";
|
|
34
34
|
import "../chunk-CM5CWO4K.js";
|
|
35
35
|
import "../chunk-ZCTUYGNV.js";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D2b-A · nested choices on pool members (design §2.2, user rulings 2026-09-27: GENERAL and RECURSIVE).
|
|
3
|
+
*
|
|
4
|
+
* A pool member (an invocation, a maneuver, a fighting-style option, ...) may carry its own choices: Lessons of the First
|
|
5
|
+
* Ones' Origin feat, Superior Technique's maneuver, Blessed and Druidic Warrior's cantrips, Pact of the Tome's cantrips
|
|
6
|
+
* and rituals, the three blasts' cantrip. A nested pick lives in the pool's ANCHOR block under
|
|
7
|
+
* `<poolId>:<pickKey>:<choiceId>` (a nested feat's own children under `<poolId>:<pickKey>:feat:<childId>`, the decision
|
|
8
|
+
* engine's prefix chaining), keyed by the stored pick string, so reordering or adding picks never moves it.
|
|
9
|
+
*
|
|
10
|
+
* The choices are the member's authored `choices`; absent (every note in the vault today), they are DERIVED at read time
|
|
11
|
+
* from the raw keys the notes already carry (`feat_progression`, `optionalfeature_progression`, `additional_spells`
|
|
12
|
+
* with `choose`, a `spell-choose` prerequisite), so existing notes work with no re-import. Authored `choices` win.
|
|
13
|
+
*/
|
|
14
|
+
import type { Character, ChoiceValue, FeatVia, ResolvedCharacter, ResolvedClass } from "./pc.types.js";
|
|
15
|
+
import type { Choice } from "@archivist-gg/dnd5e/types/choice";
|
|
16
|
+
import type { OptionalFeatureEntity } from "@archivist-gg/dnd5e/types/optional-feature.types";
|
|
17
|
+
import type { FeatEntity } from "@archivist-gg/dnd5e/feat/feat.types";
|
|
18
|
+
/** Whether `ch` names a target rather than granting what it picks (the data flag `target: true`, which the spell-choose
|
|
19
|
+
* derivation below writes and an authored note may carry). */
|
|
20
|
+
export declare function isTargetChoice(ch: Choice): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The member's choices: its authored `choices`, else the ones its raw keys ask for (see the module docblock). Pure; the
|
|
23
|
+
* derived rows carry the member's edition so a pick never offers the other edition's twin.
|
|
24
|
+
*/
|
|
25
|
+
export declare function memberChoices(entity: OptionalFeatureEntity | null | undefined): Choice[];
|
|
26
|
+
/** One stored pool pick whose member carries choices, with the block its nested picks live in. */
|
|
27
|
+
export interface PoolMemberSite {
|
|
28
|
+
classIndex: number;
|
|
29
|
+
/** The pool's anchor level (the block's key in `choices`). */
|
|
30
|
+
level: number;
|
|
31
|
+
poolId: string;
|
|
32
|
+
/** The stored pick string (a copy of a repeatable note keeps its `slug#param`). */
|
|
33
|
+
pickKey: string;
|
|
34
|
+
member: OptionalFeatureEntity;
|
|
35
|
+
memberSlug: string;
|
|
36
|
+
choices: Choice[];
|
|
37
|
+
/** `<poolId>:<pickKey>:` */
|
|
38
|
+
prefix: string;
|
|
39
|
+
/** The nested pick stored for a member choice id. */
|
|
40
|
+
read: (choiceId: string) => ChoiceValue | undefined;
|
|
41
|
+
/** The anchor block, as stored. */
|
|
42
|
+
block: Record<string, ChoiceValue>;
|
|
43
|
+
}
|
|
44
|
+
/** Structural subset of the registry the raw enumerator reads. */
|
|
45
|
+
export interface MemberRegistry {
|
|
46
|
+
getByTypeAndSlug(entityType: string, slug: string): {
|
|
47
|
+
slug: string;
|
|
48
|
+
data: Record<string, unknown>;
|
|
49
|
+
} | undefined;
|
|
50
|
+
search(query: string, entityType: string, limit: number): Array<{
|
|
51
|
+
slug: string;
|
|
52
|
+
data: Record<string, unknown>;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Every pool member site from the RAW character (the resolver's view, before pools resolve): each class's and subclass's
|
|
57
|
+
* declared pools, their anchor levels (`poolAnchorLevel`, the one derivation `resolvePool` uses), the picks stored there,
|
|
58
|
+
* each resolved to its note (full slug, else bare). A pick with no note, or a note with no choices, yields no site, so an
|
|
59
|
+
* orphan nested key is inert.
|
|
60
|
+
*/
|
|
61
|
+
export declare function poolMemberSites(classes: ResolvedClass[], registry: MemberRegistry): PoolMemberSite[];
|
|
62
|
+
/** The same sites read from a RESOLVED character's pools (the ledger's, the proficiency walk's and recalc's view). */
|
|
63
|
+
export declare function poolMemberSitesOf(resolved: Pick<ResolvedCharacter, "pools" | "classes">): PoolMemberSite[];
|
|
64
|
+
/** A feat the character picked, where it was picked, and how its own children are read. */
|
|
65
|
+
export interface FeatPickSite {
|
|
66
|
+
slug: string;
|
|
67
|
+
classIndex: number;
|
|
68
|
+
level: number | null;
|
|
69
|
+
via: FeatVia | null;
|
|
70
|
+
/** A child choice of THIS feat, as stored (`feat:<id>` in the slot's block, or `<prefix>feat:<id>` under a member). */
|
|
71
|
+
read: (childId: string) => ChoiceValue | undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Every feat pick with its own read (design §2.2 step 4): the class-slot picks (`choices[<level>].feat`, children under
|
|
75
|
+
* `feat:<id>`) and the pool-member picks (a member choice of `entity_type: feat`, children under `<prefix>feat:<id>`).
|
|
76
|
+
* The ONE list the four feat readers walk (the resolver's feats and feat spells, the proficiency walk, ability points).
|
|
77
|
+
* `classSlugOf` names a class for the provenance. NOT de-duplicated: a feat taken twice (Magic Initiate, one spell list
|
|
78
|
+
* each) is two sites with two reads; a reader that lists feats de-duplicates by slug itself (first wins).
|
|
79
|
+
*/
|
|
80
|
+
export declare function featPickSites(classEntries: ReadonlyArray<{
|
|
81
|
+
choices?: Character["class"][number]["choices"] | ResolvedClass["choices"];
|
|
82
|
+
}> | undefined, memberSites: PoolMemberSite[], classSlugOf: (classIndex: number) => string | null): FeatPickSite[];
|
|
83
|
+
/** Look a feat pick up in the resolved feats (by slug, then bare slug). */
|
|
84
|
+
export declare function featOfSite(site: FeatPickSite, feats: ReadonlyArray<FeatEntity>): FeatEntity | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* The nested keys an array write to `key` orphans (design §2.2 step 8): every `<key>:<k>:*` whose `k` was stored before
|
|
87
|
+
* and is not in `next`. Pure; the writer deletes them in the same write, so a re-pick never resurrects an old answer.
|
|
88
|
+
* A key that is not a pool (no array stored) orphans nothing.
|
|
89
|
+
*/
|
|
90
|
+
export declare function nestedPickKeysToPrune(block: Record<string, unknown> | undefined, key: string, next: readonly string[]): string[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
featOfSite,
|
|
3
|
+
featPickSites,
|
|
4
|
+
isTargetChoice,
|
|
5
|
+
memberChoices,
|
|
6
|
+
nestedPickKeysToPrune,
|
|
7
|
+
poolMemberSites,
|
|
8
|
+
poolMemberSitesOf
|
|
9
|
+
} from "../chunk-HTYMW5CH.js";
|
|
10
|
+
import "../chunk-3VZZDKRA.js";
|
|
11
|
+
import "../chunk-W6GC6OKK.js";
|
|
12
|
+
import "../chunk-B3DP42OM.js";
|
|
13
|
+
import "../chunk-IUAAXXNO.js";
|
|
14
|
+
import "../chunk-IHE6KVC3.js";
|
|
15
|
+
import "../chunk-LHZXYFBU.js";
|
|
16
|
+
import "../chunk-YBLDE5CG.js";
|
|
17
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
18
|
+
import "../chunk-LVQLWRCU.js";
|
|
19
|
+
import "../chunk-CM5CWO4K.js";
|
|
20
|
+
import "../chunk-ZCTUYGNV.js";
|
|
21
|
+
import "../chunk-3TM34RSJ.js";
|
|
22
|
+
import "../chunk-PDJSUH24.js";
|
|
23
|
+
import "../chunk-WELIKLZF.js";
|
|
24
|
+
export {
|
|
25
|
+
featOfSite,
|
|
26
|
+
featPickSites,
|
|
27
|
+
isTargetChoice,
|
|
28
|
+
memberChoices,
|
|
29
|
+
nestedPickKeysToPrune,
|
|
30
|
+
poolMemberSites,
|
|
31
|
+
poolMemberSitesOf
|
|
32
|
+
};
|
package/dist/pc/pc.parser.js
CHANGED
package/dist/pc/pc.pools.d.ts
CHANGED
|
@@ -9,6 +9,13 @@ export interface PoolRegistry {
|
|
|
9
9
|
getByTypeAndSlug(entityType: string, slug: string): RegisteredEntity | undefined;
|
|
10
10
|
}
|
|
11
11
|
export declare function levelPrereqMax(d: OptionalFeatureEntity): number;
|
|
12
|
+
/** The pool's ANCHOR level (its picks live in `choices[anchorLevel][pool.id]`): the first level whose count column
|
|
13
|
+
* carries a value of at least 1, else 1; `columnSeen` says whether any level carried the column at all. ONE derivation
|
|
14
|
+
* shared by `resolvePool` and the nested-choice enumerator (D2b-A, `pc.member-choices.ts`), so the two always agree. */
|
|
15
|
+
export declare function poolAnchorLevel(entity: Pick<NonNullable<ResolvedClass["entity"]>, "table">, pool: Pick<SelectionPool, "count">): {
|
|
16
|
+
anchorLevel: number;
|
|
17
|
+
columnSeen: boolean;
|
|
18
|
+
};
|
|
12
19
|
export declare function resolvePool(rc: ResolvedClass, classIndex: number, pool: SelectionPool, registry: PoolRegistry, index: ResourceIndex, edition?: string): ResolvedPool;
|
|
13
20
|
export declare function resolveAllPools(resolved: ResolvedCharacter, registry: PoolRegistry, index: ResourceIndex): ResolvedPool[];
|
|
14
21
|
/** The stored picks that survived resolution but are NOT in the collapsed `available` list, compared by FULL
|
package/dist/pc/pc.pools.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
levelPrereqMax,
|
|
3
|
+
poolAnchorLevel,
|
|
3
4
|
resolveAllPools,
|
|
4
5
|
resolvePool,
|
|
5
6
|
strandedPicks
|
|
6
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-3VZZDKRA.js";
|
|
7
8
|
import "../chunk-W6GC6OKK.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-B3DP42OM.js";
|
|
9
10
|
import "../chunk-IUAAXXNO.js";
|
|
10
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
11
11
|
import "../chunk-IHE6KVC3.js";
|
|
12
12
|
import "../chunk-LHZXYFBU.js";
|
|
13
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
13
14
|
import "../chunk-LVQLWRCU.js";
|
|
14
15
|
import "../chunk-CM5CWO4K.js";
|
|
15
16
|
import "../chunk-ZCTUYGNV.js";
|
|
@@ -18,6 +19,7 @@ import "../chunk-PDJSUH24.js";
|
|
|
18
19
|
import "../chunk-WELIKLZF.js";
|
|
19
20
|
export {
|
|
20
21
|
levelPrereqMax,
|
|
22
|
+
poolAnchorLevel,
|
|
21
23
|
resolveAllPools,
|
|
22
24
|
resolvePool,
|
|
23
25
|
strandedPicks
|
|
@@ -2,36 +2,37 @@ import {
|
|
|
2
2
|
collectChosenProficiencies,
|
|
3
3
|
collectProficiencyGrants,
|
|
4
4
|
computeEffectiveProficiencies
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-ONTGZR5T.js";
|
|
6
6
|
import "../chunk-2LULMQTF.js";
|
|
7
7
|
import "../chunk-H5PTKYXL.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-DPUJDOKV.js";
|
|
10
|
-
import "../chunk-4BZ47YJ4.js";
|
|
8
|
+
import "../chunk-TULQ4FFX.js";
|
|
11
9
|
import "../chunk-TOM66P2P.js";
|
|
12
10
|
import "../chunk-KU3YLF6D.js";
|
|
11
|
+
import "../chunk-HTYMW5CH.js";
|
|
12
|
+
import "../chunk-KSTV7J2U.js";
|
|
13
|
+
import "../chunk-DPUJDOKV.js";
|
|
14
|
+
import "../chunk-LBEXLN6I.js";
|
|
13
15
|
import {
|
|
14
16
|
proficiencyLabel,
|
|
15
17
|
toProfSlug
|
|
16
18
|
} from "../chunk-RLGQ5PZZ.js";
|
|
17
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-3VZZDKRA.js";
|
|
18
20
|
import "../chunk-W6GC6OKK.js";
|
|
19
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-B3DP42OM.js";
|
|
20
22
|
import "../chunk-IUAAXXNO.js";
|
|
21
23
|
import "../chunk-YHYTW5QA.js";
|
|
22
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-VRV3NNTA.js";
|
|
23
25
|
import "../chunk-PVCEA4HZ.js";
|
|
24
|
-
import "../chunk-LBEXLN6I.js";
|
|
25
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
26
26
|
import "../chunk-IHE6KVC3.js";
|
|
27
27
|
import "../chunk-LHZXYFBU.js";
|
|
28
|
+
import "../chunk-YBLDE5CG.js";
|
|
29
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
28
30
|
import "../chunk-LVQLWRCU.js";
|
|
29
31
|
import "../chunk-CM5CWO4K.js";
|
|
30
|
-
import "../chunk-ZCTUYGNV.js";
|
|
31
|
-
import "../chunk-YBLDE5CG.js";
|
|
32
32
|
import "../chunk-EVMUJYUD.js";
|
|
33
33
|
import "../chunk-VTTA2ALZ.js";
|
|
34
|
-
import "../chunk-
|
|
34
|
+
import "../chunk-ZCTUYGNV.js";
|
|
35
|
+
import "../chunk-7Q2VPKCD.js";
|
|
35
36
|
import "../chunk-ZDAEGJH4.js";
|
|
36
37
|
import "../chunk-3TM34RSJ.js";
|
|
37
38
|
import "../chunk-PDJSUH24.js";
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
qualifiedGrantCovers
|
|
3
|
+
} from "../chunk-3LWMFYKS.js";
|
|
4
|
+
import "../chunk-YDGMBMYI.js";
|
|
1
5
|
import {
|
|
2
6
|
normKey
|
|
3
7
|
} from "../chunk-RLGQ5PZZ.js";
|
|
8
|
+
import "../chunk-ZCTUYGNV.js";
|
|
4
9
|
|
|
5
10
|
// src/pc/pc.proficiency-query.ts
|
|
6
11
|
function isProficientWithWeapon(weapon, profs) {
|
|
7
12
|
if (profs.weapons.specific.some((e) => e === weapon.slug || normKey(e) === normKey(weapon.name))) return true;
|
|
13
|
+
if (profs.weapons.specific.some((e) => qualifiedGrantCovers(e, weapon))) return true;
|
|
8
14
|
const baseCategory = weapon.category.split("-")[0];
|
|
9
15
|
return profs.weapons.categories.includes(baseCategory);
|
|
10
16
|
}
|