@archivist-gg/dnd5e 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/background/background.codec.js +3 -3
- package/dist/background/background.parser.js +2 -2
- package/dist/background/background.schema.d.ts +8 -0
- package/dist/background/background.schema.js +5 -3
- package/dist/{chunk-DZXSWSBP.js → chunk-5ZBE4CWV.js} +1 -1
- package/dist/{chunk-M2EMFD6S.js → chunk-6IRYTM5V.js} +5 -0
- package/dist/chunk-7TEK5KK7.js +49 -0
- package/dist/{chunk-VTYUBINW.js → chunk-BIK4DFWK.js} +1 -1
- package/dist/{chunk-EMOORSQ7.js → chunk-D3CLOBE3.js} +4 -1
- package/dist/chunk-O5EYMKFH.js +6 -0
- package/dist/{chunk-TUIFSVLI.js → chunk-SE7AZDR3.js} +1 -0
- package/dist/{chunk-A4WENOUQ.js → chunk-TN6ZLTNU.js} +1 -4
- package/dist/{chunk-5MZSB6OM.js → chunk-TNUFPIXI.js} +41 -20
- package/dist/index.js +90 -19
- package/dist/item/item.ai-schema.d.ts +1 -1
- package/dist/pc/pc.decision-engine.d.ts +13 -0
- package/dist/pc/pc.decision-engine.js +5 -3
- package/dist/pc/pc.equipment.js +2 -1
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.js +3 -3
- package/dist/pc/pc.proficiencies.d.ts +31 -0
- package/dist/pc/pc.proficiencies.js +96 -23
- package/dist/pc/pc.proficiency-normalize.d.ts +5 -0
- package/dist/pc/pc.proficiency-query.js +5 -1
- package/dist/pc/pc.recalc.js +45 -35
- package/dist/pc/pc.resolver.js +3 -3
- package/dist/pc/pc.schema.d.ts +8 -4
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.spellcasting.d.ts +5 -1
- package/dist/pc/pc.spellcasting.js +3 -1
- package/dist/pc/pc.types.d.ts +2 -4
- package/dist/types/choice.d.ts +5 -0
- package/dist/types/choice.js +9 -3
- package/package.json +1 -1
- package/dist/chunk-BH6AMZVY.js +0 -25
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
backgroundCodec
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-BIK4DFWK.js";
|
|
4
|
+
import "../chunk-5ZBE4CWV.js";
|
|
5
|
+
import "../chunk-SE7AZDR3.js";
|
|
6
6
|
import "../chunk-3DZ74AKK.js";
|
|
7
7
|
import "../chunk-NXSWH3AE.js";
|
|
8
8
|
import "../chunk-NXR3BD2V.js";
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare const langProfSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
kind: z.ZodLiteral<"fixed">;
|
|
4
|
+
languages: z.ZodArray<z.ZodString>;
|
|
5
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6
|
+
kind: z.ZodLiteral<"choice">;
|
|
7
|
+
count: z.ZodNumber;
|
|
8
|
+
from: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
9
|
+
}, z.core.$strip>], "kind">;
|
|
2
10
|
export declare const backgroundEntitySchema: z.ZodObject<{
|
|
3
11
|
slug: z.ZodString;
|
|
4
12
|
name: z.ZodString;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
backgroundEntitySchema
|
|
3
|
-
|
|
2
|
+
backgroundEntitySchema,
|
|
3
|
+
langProfSchema
|
|
4
|
+
} from "../chunk-SE7AZDR3.js";
|
|
4
5
|
import "../chunk-3DZ74AKK.js";
|
|
5
6
|
import "../chunk-NXSWH3AE.js";
|
|
6
7
|
import "../chunk-NXR3BD2V.js";
|
|
7
8
|
export {
|
|
8
|
-
backgroundEntitySchema
|
|
9
|
+
backgroundEntitySchema,
|
|
10
|
+
langProfSchema
|
|
9
11
|
};
|
|
@@ -24,6 +24,10 @@ function resolveSpellcasting(rc) {
|
|
|
24
24
|
table
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
function effectiveSpellcastingAbility(classSlug, dataAbility, overrides) {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
return (_b = (_a = overrides.spellcasting_ability_by_class) == null ? void 0 : _a[classSlug]) != null ? _b : dataAbility;
|
|
30
|
+
}
|
|
27
31
|
function normalizeKnownSpell(entry) {
|
|
28
32
|
var _a, _b;
|
|
29
33
|
if (typeof entry === "string") {
|
|
@@ -263,6 +267,7 @@ function computeSpellLimits(inputs) {
|
|
|
263
267
|
|
|
264
268
|
export {
|
|
265
269
|
resolveSpellcasting,
|
|
270
|
+
effectiveSpellcastingAbility,
|
|
266
271
|
normalizeKnownSpell,
|
|
267
272
|
deriveSpellSlots,
|
|
268
273
|
computeSpellLimits
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/types/choice.ts
|
|
2
|
+
var ALL_SKILL_SLUGS = [
|
|
3
|
+
"acrobatics",
|
|
4
|
+
"animal-handling",
|
|
5
|
+
"arcana",
|
|
6
|
+
"athletics",
|
|
7
|
+
"deception",
|
|
8
|
+
"history",
|
|
9
|
+
"insight",
|
|
10
|
+
"intimidation",
|
|
11
|
+
"investigation",
|
|
12
|
+
"medicine",
|
|
13
|
+
"nature",
|
|
14
|
+
"perception",
|
|
15
|
+
"performance",
|
|
16
|
+
"persuasion",
|
|
17
|
+
"religion",
|
|
18
|
+
"sleight-of-hand",
|
|
19
|
+
"stealth",
|
|
20
|
+
"survival"
|
|
21
|
+
];
|
|
22
|
+
var STANDARD_LANGUAGES = [
|
|
23
|
+
"common",
|
|
24
|
+
"dwarvish",
|
|
25
|
+
"elvish",
|
|
26
|
+
"giant",
|
|
27
|
+
"gnomish",
|
|
28
|
+
"goblin",
|
|
29
|
+
"halfling",
|
|
30
|
+
"orc"
|
|
31
|
+
];
|
|
32
|
+
var EXOTIC_LANGUAGES = [
|
|
33
|
+
"abyssal",
|
|
34
|
+
"celestial",
|
|
35
|
+
"deep-speech",
|
|
36
|
+
"draconic",
|
|
37
|
+
"infernal",
|
|
38
|
+
"primordial",
|
|
39
|
+
"sylvan",
|
|
40
|
+
"undercommon"
|
|
41
|
+
];
|
|
42
|
+
var ALL_LANGUAGES = [...STANDARD_LANGUAGES, ...EXOTIC_LANGUAGES];
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
ALL_SKILL_SLUGS,
|
|
46
|
+
STANDARD_LANGUAGES,
|
|
47
|
+
EXOTIC_LANGUAGES,
|
|
48
|
+
ALL_LANGUAGES
|
|
49
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
classifyWeaponRange
|
|
3
3
|
} from "./chunk-353WXS6S.js";
|
|
4
|
+
import {
|
|
5
|
+
normKey
|
|
6
|
+
} from "./chunk-O5EYMKFH.js";
|
|
4
7
|
import {
|
|
5
8
|
defaultSlotForType,
|
|
6
9
|
effectiveArmor,
|
|
@@ -361,7 +364,7 @@ function attackAbility(weapon, mods, weaponAbilities) {
|
|
|
361
364
|
}
|
|
362
365
|
function isWeaponSlugProficient(weapon, weaponSlug, profs) {
|
|
363
366
|
const wp = profs.weapons;
|
|
364
|
-
if (wp.specific.
|
|
367
|
+
if (wp.specific.some((e) => e === weaponSlug || normKey(e) === normKey(weapon.name))) return true;
|
|
365
368
|
const cat = weapon.category;
|
|
366
369
|
if (typeof cat === "string") {
|
|
367
370
|
if (/^simple\b/.test(cat) && wp.categories.includes("simple")) return true;
|
|
@@ -102,10 +102,7 @@ var characterOverridesSchema = z.object({
|
|
|
102
102
|
ac: z.number().int().optional(),
|
|
103
103
|
speed: z.number().int().optional(),
|
|
104
104
|
initiative: z.number().int().optional(),
|
|
105
|
-
|
|
106
|
-
saveDC: z.number().int().optional(),
|
|
107
|
-
attackBonus: z.number().int().optional()
|
|
108
|
-
}).optional(),
|
|
105
|
+
spellcasting_ability_by_class: z.record(z.string(), abilityEnum).optional(),
|
|
109
106
|
// Character-level DC-ability fallback for own-ability-less spells (e.g. a Spell
|
|
110
107
|
// Scroll cast by a non-caster). Same ability enum as the per-instance spell_ability.
|
|
111
108
|
spellcasting_ability: abilityEnum.optional(),
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ALL_LANGUAGES,
|
|
2
3
|
ALL_SKILL_SLUGS
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7TEK5KK7.js";
|
|
4
5
|
import {
|
|
6
|
+
effectiveSpellcastingAbility,
|
|
5
7
|
normalizeKnownSpell,
|
|
6
8
|
resolveSpellcasting
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6IRYTM5V.js";
|
|
8
10
|
import {
|
|
9
11
|
readTableColumn
|
|
10
12
|
} from "./chunk-5XUXXAQJ.js";
|
|
@@ -134,8 +136,9 @@ var PCResolver = class {
|
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
138
|
const ownSpellcastingAbility = (_h = classes.map((c) => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
if (!c.entity) return null;
|
|
140
|
+
const p = resolveSpellcasting(c);
|
|
141
|
+
return p ? effectiveSpellcastingAbility(c.entity.slug, p.ability, character.overrides) : null;
|
|
139
142
|
}).find((a) => a != null)) != null ? _h : null;
|
|
140
143
|
spells.push(...collectItemGrantedSpells(character, ownSpellcastingAbility, this.entities, warnings));
|
|
141
144
|
const chosenMasteries = collectChosenWeaponMasteries(character);
|
|
@@ -545,7 +548,7 @@ function enumerateOptions(choice, ctx, ownerBare) {
|
|
|
545
548
|
return filtered.map((e) => ({ value: e.slug, label: e.name, entity: e }));
|
|
546
549
|
}
|
|
547
550
|
case "select-proficiency": {
|
|
548
|
-
const pool = (_a = choice.from) != null ? _a : choice.domain === "skill" ? [...ALL_SKILL_SLUGS] : [];
|
|
551
|
+
const pool = (_a = choice.from) != null ? _a : choice.domain === "skill" ? [...ALL_SKILL_SLUGS] : choice.domain === "language" ? [...ALL_LANGUAGES] : [];
|
|
549
552
|
return pool.map((v) => ({ value: v, label: v.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()) }));
|
|
550
553
|
}
|
|
551
554
|
case "ability-points": {
|
|
@@ -648,22 +651,11 @@ function buildSubclassItem(choice, source, level, featureName, c, ctx, ownerBare
|
|
|
648
651
|
status: selected ? "resolved" : "unresolved"
|
|
649
652
|
};
|
|
650
653
|
}
|
|
651
|
-
function
|
|
654
|
+
function visitProficiencyChoices(resolved, visit) {
|
|
652
655
|
var _a, _b;
|
|
653
|
-
const out = { skills: [], expertise: [], languages: [], tools: [] };
|
|
654
|
-
const apply = (choice, selected) => {
|
|
655
|
-
if (choice.kind !== "select-proficiency") return;
|
|
656
|
-
const vals = Array.isArray(selected) ? selected : typeof selected === "string" ? [selected] : [];
|
|
657
|
-
const pool = choice.from;
|
|
658
|
-
const valid = pool ? vals.filter((v) => pool.includes(v)) : vals;
|
|
659
|
-
const bucket = choice.domain === "skill" ? choice.expertise ? out.expertise : out.skills : choice.domain === "language" ? out.languages : choice.domain === "tool" ? out.tools : null;
|
|
660
|
-
if (bucket) {
|
|
661
|
-
for (const v of valid) if (!bucket.includes(v)) bucket.push(v);
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
656
|
const walk = (choices, read) => {
|
|
665
657
|
for (const ch of choices != null ? choices : []) {
|
|
666
|
-
|
|
658
|
+
visit(ch, read(ch.id));
|
|
667
659
|
if (ch.kind === "select-inline") {
|
|
668
660
|
const sel = read(ch.id);
|
|
669
661
|
const branch = typeof sel === "string" ? ch.options.find((o) => o.value === sel) : void 0;
|
|
@@ -680,7 +672,7 @@ function collectChosenProficiencies(resolved) {
|
|
|
680
672
|
return (_a3 = c.choices[lvl]) == null ? void 0 : _a3[id];
|
|
681
673
|
};
|
|
682
674
|
if (i === 0 && ((_b2 = (_a2 = entity.skill_choices) == null ? void 0 : _a2.from) == null ? void 0 : _b2.length)) {
|
|
683
|
-
|
|
675
|
+
visit({
|
|
684
676
|
kind: "select-proficiency",
|
|
685
677
|
id: "skills",
|
|
686
678
|
count: entity.skill_choices.count,
|
|
@@ -704,11 +696,39 @@ function collectChosenProficiencies(resolved) {
|
|
|
704
696
|
if (resolved.background) {
|
|
705
697
|
walk(resolved.background.choices, originRead("background"));
|
|
706
698
|
if (resolved.background.feature) {
|
|
707
|
-
|
|
699
|
+
const feature = resolved.background.feature;
|
|
700
|
+
walk(feature.choices, originRead("background"));
|
|
708
701
|
}
|
|
709
702
|
}
|
|
703
|
+
}
|
|
704
|
+
function collectChosenProficiencies(resolved) {
|
|
705
|
+
const out = { skills: [], expertise: [], languages: [], tools: [] };
|
|
706
|
+
visitProficiencyChoices(resolved, (choice, selected) => {
|
|
707
|
+
if (choice.kind !== "select-proficiency") return;
|
|
708
|
+
const vals = Array.isArray(selected) ? selected : typeof selected === "string" ? [selected] : [];
|
|
709
|
+
const pool = choice.from;
|
|
710
|
+
const valid = pool ? vals.filter((v) => pool.includes(v)) : vals;
|
|
711
|
+
const bucket = choice.domain === "skill" ? choice.expertise ? out.expertise : out.skills : choice.domain === "language" ? out.languages : choice.domain === "tool" ? out.tools : null;
|
|
712
|
+
if (bucket) {
|
|
713
|
+
for (const v of valid) if (!bucket.includes(v)) bucket.push(v);
|
|
714
|
+
}
|
|
715
|
+
});
|
|
710
716
|
return out;
|
|
711
717
|
}
|
|
718
|
+
function collectLanguageToolChoiceStatus(resolved) {
|
|
719
|
+
const languages = [];
|
|
720
|
+
const tools = [];
|
|
721
|
+
visitProficiencyChoices(resolved, (choice, selected) => {
|
|
722
|
+
if (choice.kind !== "select-proficiency") return;
|
|
723
|
+
if (choice.domain !== "language" && choice.domain !== "tool") return;
|
|
724
|
+
const vals = Array.isArray(selected) ? selected : typeof selected === "string" ? [selected] : [];
|
|
725
|
+
const pool = choice.from;
|
|
726
|
+
const valid = pool ? vals.filter((v) => pool.includes(v)) : vals;
|
|
727
|
+
const status = { id: choice.id, count: choice.count, selected: valid.length };
|
|
728
|
+
(choice.domain === "language" ? languages : tools).push(status);
|
|
729
|
+
});
|
|
730
|
+
return { languages, tools };
|
|
731
|
+
}
|
|
712
732
|
function collectChosenAbilityPoints(resolved) {
|
|
713
733
|
var _a, _b, _c;
|
|
714
734
|
const oc = (_a = resolved.definition.origin_choices) != null ? _a : {};
|
|
@@ -1084,6 +1104,7 @@ export {
|
|
|
1084
1104
|
wikilinkTailSlug,
|
|
1085
1105
|
__matchesFilterForTest,
|
|
1086
1106
|
collectChosenProficiencies,
|
|
1107
|
+
collectLanguageToolChoiceStatus,
|
|
1087
1108
|
collectChosenAbilityPoints,
|
|
1088
1109
|
buildDecisionLedger
|
|
1089
1110
|
};
|
package/dist/index.js
CHANGED
|
@@ -82,9 +82,9 @@ import "./chunk-HCP3GMHS.js";
|
|
|
82
82
|
import "./chunk-XJNECUPT.js";
|
|
83
83
|
import {
|
|
84
84
|
backgroundCodec
|
|
85
|
-
} from "./chunk-
|
|
86
|
-
import "./chunk-
|
|
87
|
-
import "./chunk-
|
|
85
|
+
} from "./chunk-BIK4DFWK.js";
|
|
86
|
+
import "./chunk-5ZBE4CWV.js";
|
|
87
|
+
import "./chunk-SE7AZDR3.js";
|
|
88
88
|
import "./chunk-3DZ74AKK.js";
|
|
89
89
|
import "./chunk-NXSWH3AE.js";
|
|
90
90
|
import "./chunk-NXR3BD2V.js";
|
|
@@ -137665,7 +137665,14 @@ var background_2024_default = [
|
|
|
137665
137665
|
]
|
|
137666
137666
|
}
|
|
137667
137667
|
],
|
|
137668
|
-
language_proficiencies: [
|
|
137668
|
+
language_proficiencies: [
|
|
137669
|
+
{
|
|
137670
|
+
kind: "fixed",
|
|
137671
|
+
languages: [
|
|
137672
|
+
"common"
|
|
137673
|
+
]
|
|
137674
|
+
}
|
|
137675
|
+
],
|
|
137669
137676
|
equipment: [
|
|
137670
137677
|
{
|
|
137671
137678
|
kind: "choice",
|
|
@@ -137713,6 +137720,12 @@ var background_2024_default = [
|
|
|
137713
137720
|
"wis",
|
|
137714
137721
|
"cha"
|
|
137715
137722
|
]
|
|
137723
|
+
},
|
|
137724
|
+
{
|
|
137725
|
+
kind: "select-proficiency",
|
|
137726
|
+
id: "languages",
|
|
137727
|
+
count: 2,
|
|
137728
|
+
domain: "language"
|
|
137716
137729
|
}
|
|
137717
137730
|
]
|
|
137718
137731
|
},
|
|
@@ -137734,7 +137747,14 @@ var background_2024_default = [
|
|
|
137734
137747
|
]
|
|
137735
137748
|
}
|
|
137736
137749
|
],
|
|
137737
|
-
language_proficiencies: [
|
|
137750
|
+
language_proficiencies: [
|
|
137751
|
+
{
|
|
137752
|
+
kind: "fixed",
|
|
137753
|
+
languages: [
|
|
137754
|
+
"common"
|
|
137755
|
+
]
|
|
137756
|
+
}
|
|
137757
|
+
],
|
|
137738
137758
|
equipment: [
|
|
137739
137759
|
{
|
|
137740
137760
|
kind: "choice",
|
|
@@ -137786,6 +137806,12 @@ var background_2024_default = [
|
|
|
137786
137806
|
"con",
|
|
137787
137807
|
"int"
|
|
137788
137808
|
]
|
|
137809
|
+
},
|
|
137810
|
+
{
|
|
137811
|
+
kind: "select-proficiency",
|
|
137812
|
+
id: "languages",
|
|
137813
|
+
count: 2,
|
|
137814
|
+
domain: "language"
|
|
137789
137815
|
}
|
|
137790
137816
|
]
|
|
137791
137817
|
},
|
|
@@ -137807,7 +137833,14 @@ var background_2024_default = [
|
|
|
137807
137833
|
]
|
|
137808
137834
|
}
|
|
137809
137835
|
],
|
|
137810
|
-
language_proficiencies: [
|
|
137836
|
+
language_proficiencies: [
|
|
137837
|
+
{
|
|
137838
|
+
kind: "fixed",
|
|
137839
|
+
languages: [
|
|
137840
|
+
"common"
|
|
137841
|
+
]
|
|
137842
|
+
}
|
|
137843
|
+
],
|
|
137811
137844
|
equipment: [
|
|
137812
137845
|
{
|
|
137813
137846
|
kind: "choice",
|
|
@@ -137858,6 +137891,12 @@ var background_2024_default = [
|
|
|
137858
137891
|
"int",
|
|
137859
137892
|
"wis"
|
|
137860
137893
|
]
|
|
137894
|
+
},
|
|
137895
|
+
{
|
|
137896
|
+
kind: "select-proficiency",
|
|
137897
|
+
id: "languages",
|
|
137898
|
+
count: 2,
|
|
137899
|
+
domain: "language"
|
|
137861
137900
|
}
|
|
137862
137901
|
]
|
|
137863
137902
|
},
|
|
@@ -137871,15 +137910,15 @@ var background_2024_default = [
|
|
|
137871
137910
|
"athletics",
|
|
137872
137911
|
"intimidation"
|
|
137873
137912
|
],
|
|
137874
|
-
tool_proficiencies: [
|
|
137913
|
+
tool_proficiencies: [],
|
|
137914
|
+
language_proficiencies: [
|
|
137875
137915
|
{
|
|
137876
137916
|
kind: "fixed",
|
|
137877
|
-
|
|
137878
|
-
"
|
|
137917
|
+
languages: [
|
|
137918
|
+
"common"
|
|
137879
137919
|
]
|
|
137880
137920
|
}
|
|
137881
137921
|
],
|
|
137882
|
-
language_proficiencies: [],
|
|
137883
137922
|
equipment: [
|
|
137884
137923
|
{
|
|
137885
137924
|
kind: "choice",
|
|
@@ -137939,6 +137978,12 @@ var background_2024_default = [
|
|
|
137939
137978
|
id: "tool",
|
|
137940
137979
|
count: 1,
|
|
137941
137980
|
domain: "tool"
|
|
137981
|
+
},
|
|
137982
|
+
{
|
|
137983
|
+
kind: "select-proficiency",
|
|
137984
|
+
id: "languages",
|
|
137985
|
+
count: 2,
|
|
137986
|
+
domain: "language"
|
|
137942
137987
|
}
|
|
137943
137988
|
]
|
|
137944
137989
|
}
|
|
@@ -137961,7 +138006,10 @@ var race_2014_default = [
|
|
|
137961
138006
|
age: "Young dragonborn grow quickly. They walk hours after hatching, attain the size and development of a 10-year-old human child by the age of 3, and reach adulthood by 15. They live to be around 80.",
|
|
137962
138007
|
alignment: "Dragonborn tend to extremes, making a conscious choice for one side or the other in the cosmic war between good and evil. Most dragonborn are good, but those who side with evil can be terrible villains.",
|
|
137963
138008
|
languages: {
|
|
137964
|
-
fixed: [
|
|
138009
|
+
fixed: [
|
|
138010
|
+
"common",
|
|
138011
|
+
"draconic"
|
|
138012
|
+
]
|
|
137965
138013
|
},
|
|
137966
138014
|
variant_label: "base",
|
|
137967
138015
|
traits: [
|
|
@@ -138148,7 +138196,10 @@ var race_2014_default = [
|
|
|
138148
138196
|
age: "Dwarves mature at the same rate as humans, but they're considered young until they reach the age of 50. On average, they live about 350 years.",
|
|
138149
138197
|
alignment: "Most dwarves are lawful, believing firmly in the benefits of a well-ordered society. They tend toward good as well, with a strong sense of fair play and a belief that everyone deserves to share in the benefits of a just order.",
|
|
138150
138198
|
languages: {
|
|
138151
|
-
fixed: [
|
|
138199
|
+
fixed: [
|
|
138200
|
+
"common",
|
|
138201
|
+
"dwarvish"
|
|
138202
|
+
]
|
|
138152
138203
|
},
|
|
138153
138204
|
variant_label: "base",
|
|
138154
138205
|
traits: [
|
|
@@ -138229,7 +138280,10 @@ var race_2014_default = [
|
|
|
138229
138280
|
age: "Although elves reach physical maturity at about the same age as humans, the elven understanding of adulthood goes beyond physical growth to encompass worldly experience. An elf typically claims adulthood and an adult name around the age of 100 and can live to be 750 years old.",
|
|
138230
138281
|
alignment: "Elves love freedom, variety, and self-\xADexpression, so they lean strongly toward the gentler aspects of chaos. They value and protect others\u2019 freedom as well as their own, and they are more often good than not.",
|
|
138231
138282
|
languages: {
|
|
138232
|
-
fixed: [
|
|
138283
|
+
fixed: [
|
|
138284
|
+
"common",
|
|
138285
|
+
"elvish"
|
|
138286
|
+
]
|
|
138233
138287
|
},
|
|
138234
138288
|
variant_label: "base",
|
|
138235
138289
|
traits: [
|
|
@@ -138292,7 +138346,10 @@ var race_2014_default = [
|
|
|
138292
138346
|
age: "Gnomes mature at the same rate humans do, and most are expected to settle down into an adult life by around age 40. They can live 350 to almost 500 years.",
|
|
138293
138347
|
alignment: "Gnomes are most often good. Those who tend toward law are sages, engineers, researchers, scholars, investigators, or inventors. Those who tend toward chaos are minstrels, tricksters, wanderers, or fanciful jewelers. Gnomes are good-hearted, and even the tricksters among them are more playful than vicious.",
|
|
138294
138348
|
languages: {
|
|
138295
|
-
fixed: [
|
|
138349
|
+
fixed: [
|
|
138350
|
+
"common",
|
|
138351
|
+
"gnomish"
|
|
138352
|
+
]
|
|
138296
138353
|
},
|
|
138297
138354
|
variant_label: "base",
|
|
138298
138355
|
traits: [
|
|
@@ -138347,7 +138404,10 @@ var race_2014_default = [
|
|
|
138347
138404
|
age: "Half-elves mature at the same rate humans do and reach adulthood around the age of 20. They live much longer than humans, however, often exceeding 180 years.",
|
|
138348
138405
|
alignment: "Half-elves share the chaotic bent of their elven heritage. They value both personal freedom and creative expression, demonstrating neither love of leaders nor desire for followers. They chafe at rules, resent others' demands, and sometimes prove unreliable, or at least unpredictable.",
|
|
138349
138406
|
languages: {
|
|
138350
|
-
fixed: [
|
|
138407
|
+
fixed: [
|
|
138408
|
+
"common",
|
|
138409
|
+
"elvish"
|
|
138410
|
+
]
|
|
138351
138411
|
},
|
|
138352
138412
|
variant_label: "base",
|
|
138353
138413
|
traits: [
|
|
@@ -138436,7 +138496,10 @@ var race_2014_default = [
|
|
|
138436
138496
|
age: "Half-orcs mature a little faster than humans, reaching adulthood around age 14. They age noticeably faster and rarely live longer than 75 years.",
|
|
138437
138497
|
alignment: "Half-orcs inherit a tendency toward chaos from their orc parents and are not strongly inclined toward good. Half-orcs raised among orcs and willing to live out their lives among them are usually evil.",
|
|
138438
138498
|
languages: {
|
|
138439
|
-
fixed: [
|
|
138499
|
+
fixed: [
|
|
138500
|
+
"common",
|
|
138501
|
+
"orc"
|
|
138502
|
+
]
|
|
138440
138503
|
},
|
|
138441
138504
|
variant_label: "base",
|
|
138442
138505
|
traits: [
|
|
@@ -138507,7 +138570,10 @@ var race_2014_default = [
|
|
|
138507
138570
|
age: "A halfling reaches adulthood at the age of 20 and generally lives into the middle of his or her second century.",
|
|
138508
138571
|
alignment: "Most halflings are lawful good. As a rule, they are good-hearted and kind, hate to see others in pain, and have no tolerance for oppression. They are also very orderly and traditional, leaning heavily on the support of their community and the comfort of their old ways.",
|
|
138509
138572
|
languages: {
|
|
138510
|
-
fixed: [
|
|
138573
|
+
fixed: [
|
|
138574
|
+
"common",
|
|
138575
|
+
"halfling"
|
|
138576
|
+
]
|
|
138511
138577
|
},
|
|
138512
138578
|
variant_label: "base",
|
|
138513
138579
|
traits: [
|
|
@@ -138637,7 +138703,9 @@ var race_2014_default = [
|
|
|
138637
138703
|
age: "Humans reach adulthood in their late teens and live less than a century.",
|
|
138638
138704
|
alignment: "Humans tend toward no particular alignment. The best and the worst are found among them.",
|
|
138639
138705
|
languages: {
|
|
138640
|
-
fixed: [
|
|
138706
|
+
fixed: [
|
|
138707
|
+
"common"
|
|
138708
|
+
]
|
|
138641
138709
|
},
|
|
138642
138710
|
variant_label: "base",
|
|
138643
138711
|
traits: [
|
|
@@ -138752,7 +138820,10 @@ var race_2014_default = [
|
|
|
138752
138820
|
age: "Tieflings mature at the same rate as humans but live a few years longer.",
|
|
138753
138821
|
alignment: "Tieflings might not have an innate tendency toward evil, but many of them end up there. Evil or not, an independent nature inclines many tieflings toward a chaotic alignment.",
|
|
138754
138822
|
languages: {
|
|
138755
|
-
fixed: [
|
|
138823
|
+
fixed: [
|
|
138824
|
+
"common",
|
|
138825
|
+
"infernal"
|
|
138826
|
+
]
|
|
138756
138827
|
},
|
|
138757
138828
|
variant_label: "base",
|
|
138758
138829
|
traits: [
|
|
@@ -14,8 +14,8 @@ export declare const itemInputSchema: z.ZodObject<{
|
|
|
14
14
|
"wondrous item": "wondrous item";
|
|
15
15
|
}>;
|
|
16
16
|
rarity: z.ZodEnum<{
|
|
17
|
-
legendary: "legendary";
|
|
18
17
|
common: "common";
|
|
18
|
+
legendary: "legendary";
|
|
19
19
|
uncommon: "uncommon";
|
|
20
20
|
rare: "rare";
|
|
21
21
|
"very rare": "very rare";
|
|
@@ -80,6 +80,19 @@ export declare function collectChosenProficiencies(resolved: ResolvedCharacter):
|
|
|
80
80
|
languages: string[];
|
|
81
81
|
tools: string[];
|
|
82
82
|
};
|
|
83
|
+
export interface ChoiceStatus {
|
|
84
|
+
id: string;
|
|
85
|
+
count: number;
|
|
86
|
+
selected: number;
|
|
87
|
+
}
|
|
88
|
+
/** Per-choice status for language/tool select-proficiency decisions, using the
|
|
89
|
+
* SAME walk as collectChosenProficiencies so required/selected counts cannot
|
|
90
|
+
* diverge from the picks. `selected` counts persisted picks validated against
|
|
91
|
+
* the choice's `from` pool (stale slugs ignored, mirroring the pick fold). */
|
|
92
|
+
export declare function collectLanguageToolChoiceStatus(resolved: ResolvedCharacter): {
|
|
93
|
+
languages: ChoiceStatus[];
|
|
94
|
+
tools: ChoiceStatus[];
|
|
95
|
+
};
|
|
83
96
|
export interface OriginAbilityPoints {
|
|
84
97
|
race: Partial<Record<Ability, number>>;
|
|
85
98
|
background: Partial<Record<Ability, number>>;
|
|
@@ -3,10 +3,11 @@ import {
|
|
|
3
3
|
buildDecisionLedger,
|
|
4
4
|
collectChosenAbilityPoints,
|
|
5
5
|
collectChosenProficiencies,
|
|
6
|
+
collectLanguageToolChoiceStatus,
|
|
6
7
|
wikilinkTailSlug
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-TNUFPIXI.js";
|
|
9
|
+
import "../chunk-7TEK5KK7.js";
|
|
10
|
+
import "../chunk-6IRYTM5V.js";
|
|
10
11
|
import "../chunk-5XUXXAQJ.js";
|
|
11
12
|
import "../chunk-JEYQU3JT.js";
|
|
12
13
|
import "../chunk-N6N74K6X.js";
|
|
@@ -20,5 +21,6 @@ export {
|
|
|
20
21
|
buildDecisionLedger,
|
|
21
22
|
collectChosenAbilityPoints,
|
|
22
23
|
collectChosenProficiencies,
|
|
24
|
+
collectLanguageToolChoiceStatus,
|
|
23
25
|
wikilinkTailSlug
|
|
24
26
|
};
|
package/dist/pc/pc.equipment.js
CHANGED
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
computeAppliedBonuses,
|
|
3
3
|
computeSlotsAndAttacks,
|
|
4
4
|
emptyAppliedBonuses
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-D3CLOBE3.js";
|
|
6
6
|
import "../chunk-353WXS6S.js";
|
|
7
|
+
import "../chunk-O5EYMKFH.js";
|
|
7
8
|
import "../chunk-N6N74K6X.js";
|
|
8
9
|
import "../chunk-LWFTHJIE.js";
|
|
9
10
|
import "../chunk-DNAJRMNN.js";
|
package/dist/pc/pc.parser.js
CHANGED
package/dist/pc/pc.pools.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
levelPrereqMax,
|
|
3
3
|
resolveAllPools,
|
|
4
4
|
resolvePool
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-TNUFPIXI.js";
|
|
6
|
+
import "../chunk-7TEK5KK7.js";
|
|
7
|
+
import "../chunk-6IRYTM5V.js";
|
|
8
8
|
import "../chunk-5XUXXAQJ.js";
|
|
9
9
|
import "../chunk-JEYQU3JT.js";
|
|
10
10
|
import "../chunk-N6N74K6X.js";
|
|
@@ -1,8 +1,39 @@
|
|
|
1
1
|
import type { ResolvedCharacter } from "./pc.types.js";
|
|
2
|
+
import { type ChoiceStatus } from "./pc.decision-engine.js";
|
|
2
3
|
export interface ProficiencyAggregate {
|
|
3
4
|
armor: string[];
|
|
4
5
|
weapons: string[];
|
|
5
6
|
tools: string[];
|
|
6
7
|
languages: string[];
|
|
8
|
+
/** Unresolved language/tool decisions as "choose N" placeholders (N = count -
|
|
9
|
+
* selected, only when > 0). Additive; consumed by the plugin proficiency panel. */
|
|
10
|
+
choices: {
|
|
11
|
+
languages: string[];
|
|
12
|
+
tools: string[];
|
|
13
|
+
};
|
|
7
14
|
}
|
|
15
|
+
/** Normalized intermediate of every proficiency/language source the DISPLAY path
|
|
16
|
+
* reads, in one place. Only the class branch is a live proficiency source today
|
|
17
|
+
* (race/bg/feat `.proficiencies` object fields do not exist on those entities);
|
|
18
|
+
* race languages, bg tool/lang, and feat grants read their real fields. Chosen
|
|
19
|
+
* picks + per-choice status come from the single decision walk in
|
|
20
|
+
* pc.decision-engine so display can never diverge from the persisted picks. */
|
|
21
|
+
export interface ProficiencySources {
|
|
22
|
+
classArmor: string[];
|
|
23
|
+
classWeaponFixed: string[];
|
|
24
|
+
classWeaponCategories: string[];
|
|
25
|
+
classToolFixed: string[];
|
|
26
|
+
raceLangFixed: string[];
|
|
27
|
+
bgToolFixed: string[];
|
|
28
|
+
bgLangFixed: string[];
|
|
29
|
+
featArmor: string[];
|
|
30
|
+
featWeapons: string[];
|
|
31
|
+
featTools: string[];
|
|
32
|
+
featLanguages: string[];
|
|
33
|
+
chosenLanguages: string[];
|
|
34
|
+
chosenTools: string[];
|
|
35
|
+
languageChoices: ChoiceStatus[];
|
|
36
|
+
toolChoices: ChoiceStatus[];
|
|
37
|
+
}
|
|
38
|
+
export declare function collectProficiencySources(resolved: ResolvedCharacter): ProficiencySources;
|
|
8
39
|
export declare function aggregateProficiencies(resolved: ResolvedCharacter): ProficiencyAggregate;
|
|
@@ -1,47 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collectChosenProficiencies,
|
|
3
|
+
collectLanguageToolChoiceStatus
|
|
4
|
+
} from "../chunk-TNUFPIXI.js";
|
|
5
|
+
import "../chunk-7TEK5KK7.js";
|
|
6
|
+
import "../chunk-6IRYTM5V.js";
|
|
7
|
+
import "../chunk-5XUXXAQJ.js";
|
|
8
|
+
import "../chunk-JEYQU3JT.js";
|
|
9
|
+
import "../chunk-N6N74K6X.js";
|
|
10
|
+
import "../chunk-4LZJXJJS.js";
|
|
11
|
+
import "../chunk-LV4SNWZQ.js";
|
|
12
|
+
import "../chunk-VTTA2ALZ.js";
|
|
13
|
+
import "../chunk-NAEPSZAM.js";
|
|
14
|
+
import "../chunk-WP2CX2JO.js";
|
|
15
|
+
|
|
1
16
|
// src/pc/pc.proficiencies.ts
|
|
2
|
-
function
|
|
3
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
17
|
+
function collectProficiencySources(resolved) {
|
|
18
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
19
|
+
const classArmor = [];
|
|
20
|
+
const classWeaponFixed = [];
|
|
21
|
+
const classWeaponCategories = [];
|
|
22
|
+
const classToolFixed = [];
|
|
8
23
|
for (const c of resolved.classes) {
|
|
9
24
|
const prof = (_a = c.entity) == null ? void 0 : _a.proficiencies;
|
|
10
25
|
if (!prof) continue;
|
|
11
|
-
for (const a of (_b = prof.armor) != null ? _b : [])
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
for (const a of (_b = prof.armor) != null ? _b : []) classArmor.push(a);
|
|
27
|
+
for (const w of (_d = (_c = prof.weapons) == null ? void 0 : _c.fixed) != null ? _d : []) classWeaponFixed.push(w);
|
|
28
|
+
for (const w of (_f = (_e = prof.weapons) == null ? void 0 : _e.categories) != null ? _f : []) classWeaponCategories.push(w);
|
|
29
|
+
for (const t of (_h = (_g = prof.tools) == null ? void 0 : _g.fixed) != null ? _h : []) classToolFixed.push(t);
|
|
15
30
|
}
|
|
16
|
-
const
|
|
17
|
-
|
|
31
|
+
const raceLangFixed = [...(_k = (_j = (_i = resolved.race) == null ? void 0 : _i.languages) == null ? void 0 : _j.fixed) != null ? _k : []];
|
|
32
|
+
const bgToolFixed = [];
|
|
33
|
+
const bgLangFixed = [];
|
|
18
34
|
const bg = resolved.background;
|
|
19
35
|
if (bg) {
|
|
20
|
-
for (const entry of (
|
|
21
|
-
if (entry.kind === "fixed")
|
|
36
|
+
for (const entry of (_l = bg.tool_proficiencies) != null ? _l : []) {
|
|
37
|
+
if (entry.kind === "fixed") bgToolFixed.push(...entry.items);
|
|
22
38
|
}
|
|
23
|
-
for (const entry of (
|
|
24
|
-
if (entry.kind === "fixed")
|
|
39
|
+
for (const entry of (_m = bg.language_proficiencies) != null ? _m : []) {
|
|
40
|
+
if (entry.kind === "fixed") bgLangFixed.push(...entry.languages);
|
|
25
41
|
}
|
|
26
42
|
}
|
|
43
|
+
const featArmor = [];
|
|
44
|
+
const featWeapons = [];
|
|
45
|
+
const featTools = [];
|
|
46
|
+
const featLanguages = [];
|
|
27
47
|
for (const f of resolved.feats) {
|
|
28
|
-
const
|
|
48
|
+
const featView = f;
|
|
49
|
+
const grants = featView.proficiencies;
|
|
29
50
|
if (!grants) continue;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
featArmor.push(...(_n = grants.armor) != null ? _n : []);
|
|
52
|
+
featWeapons.push(...(_o = grants.weapons) != null ? _o : []);
|
|
53
|
+
featTools.push(...(_p = grants.tools) != null ? _p : []);
|
|
54
|
+
featLanguages.push(...(_q = grants.languages) != null ? _q : []);
|
|
34
55
|
}
|
|
56
|
+
const chosen = collectChosenProficiencies(resolved);
|
|
57
|
+
const status = collectLanguageToolChoiceStatus(resolved);
|
|
58
|
+
return {
|
|
59
|
+
classArmor,
|
|
60
|
+
classWeaponFixed,
|
|
61
|
+
classWeaponCategories,
|
|
62
|
+
classToolFixed,
|
|
63
|
+
raceLangFixed,
|
|
64
|
+
bgToolFixed,
|
|
65
|
+
bgLangFixed,
|
|
66
|
+
featArmor,
|
|
67
|
+
featWeapons,
|
|
68
|
+
featTools,
|
|
69
|
+
featLanguages,
|
|
70
|
+
chosenLanguages: chosen.languages,
|
|
71
|
+
chosenTools: chosen.tools,
|
|
72
|
+
languageChoices: status.languages,
|
|
73
|
+
toolChoices: status.tools
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function aggregateProficiencies(resolved) {
|
|
77
|
+
const src = collectProficiencySources(resolved);
|
|
78
|
+
const armor = /* @__PURE__ */ new Set();
|
|
79
|
+
const weapons = /* @__PURE__ */ new Set();
|
|
80
|
+
const tools = /* @__PURE__ */ new Set();
|
|
81
|
+
const languages = /* @__PURE__ */ new Set();
|
|
82
|
+
for (const a of src.classArmor) armor.add(prettyName(a));
|
|
83
|
+
for (const w of src.classWeaponFixed) weapons.add(prettyName(w));
|
|
84
|
+
for (const w of src.classWeaponCategories) weapons.add(prettyName(w));
|
|
85
|
+
for (const t of src.classToolFixed) tools.add(prettyName(t));
|
|
86
|
+
for (const l of src.raceLangFixed) languages.add(prettyName(l));
|
|
87
|
+
for (const t of src.bgToolFixed) tools.add(prettyName(t));
|
|
88
|
+
for (const l of src.bgLangFixed) languages.add(prettyName(l));
|
|
89
|
+
for (const a of src.featArmor) armor.add(prettyName(a));
|
|
90
|
+
for (const w of src.featWeapons) weapons.add(prettyName(w));
|
|
91
|
+
for (const t of src.featTools) tools.add(prettyName(t));
|
|
92
|
+
for (const l of src.featLanguages) languages.add(prettyName(l));
|
|
93
|
+
for (const l of src.chosenLanguages) languages.add(prettyName(l));
|
|
94
|
+
for (const t of src.chosenTools) tools.add(prettyName(t));
|
|
35
95
|
return {
|
|
36
96
|
armor: [...armor].sort(),
|
|
37
97
|
weapons: [...weapons].sort(),
|
|
38
98
|
tools: [...tools].sort(),
|
|
39
|
-
languages: [...languages].sort()
|
|
99
|
+
languages: [...languages].sort(),
|
|
100
|
+
choices: {
|
|
101
|
+
languages: placeholders(src.languageChoices),
|
|
102
|
+
tools: placeholders(src.toolChoices)
|
|
103
|
+
}
|
|
40
104
|
};
|
|
41
105
|
}
|
|
106
|
+
function placeholders(choices) {
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const c of choices) {
|
|
109
|
+
const remaining = c.count - c.selected;
|
|
110
|
+
if (remaining > 0) out.push("choose " + remaining);
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
42
114
|
function prettyName(slug) {
|
|
43
115
|
return slug.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
44
116
|
}
|
|
45
117
|
export {
|
|
46
|
-
aggregateProficiencies
|
|
118
|
+
aggregateProficiencies,
|
|
119
|
+
collectProficiencySources
|
|
47
120
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Normalized token-set key for matching class weapon DISPLAY names ("hand crossbows")
|
|
2
|
+
* against weapon-entity names ("Crossbow, hand"). EXACT equality on the key; verified
|
|
3
|
+
* collision-free across the SRD weapon set. Strip-"s" singularizer does not handle
|
|
4
|
+
* irregular plurals; no SRD weapon triggers that. */
|
|
5
|
+
export declare const normKey: (s: string) => string;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normKey
|
|
3
|
+
} from "../chunk-O5EYMKFH.js";
|
|
4
|
+
|
|
1
5
|
// src/pc/pc.proficiency-query.ts
|
|
2
6
|
function isProficientWithWeapon(weapon, profs) {
|
|
3
|
-
if (profs.weapons.specific.
|
|
7
|
+
if (profs.weapons.specific.some((e) => e === weapon.slug || normKey(e) === normKey(weapon.name))) return true;
|
|
4
8
|
const baseCategory = weapon.category.split("-")[0];
|
|
5
9
|
return profs.weapons.categories.includes(baseCategory);
|
|
6
10
|
}
|
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -4,21 +4,23 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
collectChosenAbilityPoints,
|
|
6
6
|
collectChosenProficiencies
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-TNUFPIXI.js";
|
|
8
|
+
import "../chunk-7TEK5KK7.js";
|
|
9
9
|
import {
|
|
10
10
|
computeSpellLimits,
|
|
11
11
|
deriveSpellSlots,
|
|
12
|
+
effectiveSpellcastingAbility,
|
|
12
13
|
resolveSpellcasting
|
|
13
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-6IRYTM5V.js";
|
|
14
15
|
import "../chunk-5XUXXAQJ.js";
|
|
15
16
|
import "../chunk-JEYQU3JT.js";
|
|
16
17
|
import {
|
|
17
18
|
computeAppliedBonuses,
|
|
18
19
|
computeSlotsAndAttacks,
|
|
19
20
|
emptyAppliedBonuses
|
|
20
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-D3CLOBE3.js";
|
|
21
22
|
import "../chunk-353WXS6S.js";
|
|
23
|
+
import "../chunk-O5EYMKFH.js";
|
|
22
24
|
import "../chunk-N6N74K6X.js";
|
|
23
25
|
import {
|
|
24
26
|
computeFeatureEffects
|
|
@@ -308,12 +310,18 @@ function computeAbilityScores(resolved, overrides) {
|
|
|
308
310
|
}
|
|
309
311
|
return out;
|
|
310
312
|
}
|
|
311
|
-
function
|
|
313
|
+
function normalizeArmorProf(input) {
|
|
312
314
|
var _a, _b;
|
|
313
315
|
if (!input) return { categories: [], specific: [] };
|
|
314
|
-
if (Array.isArray(input)) return { categories:
|
|
316
|
+
if (Array.isArray(input)) return { categories: input, specific: [] };
|
|
315
317
|
return { categories: (_a = input.categories) != null ? _a : [], specific: (_b = input.specific) != null ? _b : [] };
|
|
316
318
|
}
|
|
319
|
+
function normalizeWeaponToolProf(input) {
|
|
320
|
+
var _a, _b, _c;
|
|
321
|
+
if (!input) return { categories: [], specific: [] };
|
|
322
|
+
if (Array.isArray(input)) return { categories: [], specific: input };
|
|
323
|
+
return { categories: (_a = input.categories) != null ? _a : [], specific: ((_b = input.fixed) != null ? _b : []).concat((_c = input.specific) != null ? _c : []) };
|
|
324
|
+
}
|
|
317
325
|
function mergeInto(target, source) {
|
|
318
326
|
for (const c of source.categories) if (!target.categories.includes(c)) target.categories.push(c);
|
|
319
327
|
for (const s of source.specific) if (!target.specific.includes(s)) target.specific.push(s);
|
|
@@ -340,31 +348,31 @@ function computeProficiencies(resolved) {
|
|
|
340
348
|
for (const c of resolved.classes) {
|
|
341
349
|
const p = (_a = c.entity) == null ? void 0 : _a.proficiencies;
|
|
342
350
|
if (!p) continue;
|
|
343
|
-
mergeInto(armor,
|
|
344
|
-
mergeInto(weapons,
|
|
345
|
-
mergeInto(tools,
|
|
351
|
+
mergeInto(armor, normalizeArmorProf(p.armor));
|
|
352
|
+
mergeInto(weapons, normalizeWeaponToolProf(p.weapons));
|
|
353
|
+
mergeInto(tools, normalizeWeaponToolProf(p.tools));
|
|
346
354
|
(_b = p.languages) == null ? void 0 : _b.forEach((l) => languages.add(l));
|
|
347
355
|
}
|
|
348
356
|
const racePr = (_c = resolved.race) == null ? void 0 : _c.proficiencies;
|
|
349
357
|
if (racePr) {
|
|
350
|
-
mergeInto(armor,
|
|
351
|
-
mergeInto(weapons,
|
|
352
|
-
mergeInto(tools,
|
|
358
|
+
mergeInto(armor, normalizeArmorProf(racePr.armor));
|
|
359
|
+
mergeInto(weapons, normalizeWeaponToolProf(racePr.weapons));
|
|
360
|
+
mergeInto(tools, normalizeWeaponToolProf(racePr.tools));
|
|
353
361
|
(_d = racePr.languages) == null ? void 0 : _d.forEach((l) => languages.add(l));
|
|
354
362
|
}
|
|
355
363
|
const bgPr = (_e = resolved.background) == null ? void 0 : _e.proficiencies;
|
|
356
364
|
if (bgPr) {
|
|
357
|
-
mergeInto(armor,
|
|
358
|
-
mergeInto(weapons,
|
|
359
|
-
mergeInto(tools,
|
|
365
|
+
mergeInto(armor, normalizeArmorProf(bgPr.armor));
|
|
366
|
+
mergeInto(weapons, normalizeWeaponToolProf(bgPr.weapons));
|
|
367
|
+
mergeInto(tools, normalizeWeaponToolProf(bgPr.tools));
|
|
360
368
|
(_f = bgPr.languages) == null ? void 0 : _f.forEach((l) => languages.add(l));
|
|
361
369
|
}
|
|
362
370
|
for (const f of resolved.feats) {
|
|
363
371
|
const grants = f.grants_proficiency;
|
|
364
372
|
if (!grants) continue;
|
|
365
|
-
mergeInto(armor,
|
|
366
|
-
mergeInto(weapons,
|
|
367
|
-
mergeInto(tools,
|
|
373
|
+
mergeInto(armor, normalizeArmorProf(grants.armor));
|
|
374
|
+
mergeInto(weapons, normalizeWeaponToolProf(grants.weapons));
|
|
375
|
+
mergeInto(tools, normalizeWeaponToolProf(grants.tools));
|
|
368
376
|
(_g = grants.languages) == null ? void 0 : _g.forEach((l) => languages.add(l));
|
|
369
377
|
}
|
|
370
378
|
return {
|
|
@@ -376,7 +384,7 @@ function computeProficiencies(resolved) {
|
|
|
376
384
|
};
|
|
377
385
|
}
|
|
378
386
|
function recalc(resolved, registry) {
|
|
379
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y
|
|
387
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y;
|
|
380
388
|
const warnings = [];
|
|
381
389
|
const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
|
|
382
390
|
const chosenProfs = collectChosenProficiencies(resolved);
|
|
@@ -541,7 +549,7 @@ function recalc(resolved, registry) {
|
|
|
541
549
|
if (!c.entity) continue;
|
|
542
550
|
const profile = resolveSpellcasting(c);
|
|
543
551
|
if (profile) {
|
|
544
|
-
primaryCasterAbility = profile.ability;
|
|
552
|
+
primaryCasterAbility = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
|
|
545
553
|
break;
|
|
546
554
|
}
|
|
547
555
|
}
|
|
@@ -596,19 +604,21 @@ function recalc(resolved, registry) {
|
|
|
596
604
|
if (!c.entity) continue;
|
|
597
605
|
const profile = resolveSpellcasting(c);
|
|
598
606
|
if (!profile) continue;
|
|
599
|
-
const
|
|
600
|
-
const
|
|
607
|
+
const ab = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
|
|
608
|
+
const dc = saveDC(scores[ab], proficiencyBonus) + applied.spell_save_dc;
|
|
609
|
+
const atk = attackBonus(scores[ab], proficiencyBonus) + applied.spell_attack;
|
|
601
610
|
spellcastingClasses.push({
|
|
602
611
|
classSlug: c.entity.slug,
|
|
603
612
|
className: c.entity.name,
|
|
604
|
-
ability:
|
|
605
|
-
|
|
606
|
-
|
|
613
|
+
ability: ab,
|
|
614
|
+
defaultAbility: profile.ability,
|
|
615
|
+
saveDC: dc,
|
|
616
|
+
attackBonus: atk,
|
|
607
617
|
casterType: profile.casterType,
|
|
608
618
|
preparation: profile.preparation
|
|
609
619
|
});
|
|
610
620
|
slotInputs.push({ casterType: profile.casterType, level: c.level });
|
|
611
|
-
limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[
|
|
621
|
+
limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[ab] });
|
|
612
622
|
}
|
|
613
623
|
const spellcasting = spellcastingClasses.length > 0 ? {
|
|
614
624
|
ability: spellcastingClasses[0].ability,
|
|
@@ -628,20 +638,20 @@ function recalc(resolved, registry) {
|
|
|
628
638
|
const spellLimits = computeSpellLimits(limitInputs);
|
|
629
639
|
const defenses = {
|
|
630
640
|
resistances: dedupeDefenseList([
|
|
631
|
-
(
|
|
641
|
+
(_M = (_L = resolved.definition.defenses) == null ? void 0 : _L.resistances) != null ? _M : [],
|
|
632
642
|
applied.defenses.resistances,
|
|
633
643
|
featureEffects.resistances
|
|
634
644
|
]),
|
|
635
645
|
immunities: dedupeDefenseList([
|
|
636
|
-
(
|
|
646
|
+
(_O = (_N = resolved.definition.defenses) == null ? void 0 : _N.immunities) != null ? _O : [],
|
|
637
647
|
applied.defenses.immunities
|
|
638
648
|
]),
|
|
639
649
|
vulnerabilities: dedupeDefenseList([
|
|
640
|
-
(
|
|
650
|
+
(_Q = (_P = resolved.definition.defenses) == null ? void 0 : _P.vulnerabilities) != null ? _Q : [],
|
|
641
651
|
applied.defenses.vulnerabilities
|
|
642
652
|
]),
|
|
643
653
|
condition_immunities: dedupeDefenseList([
|
|
644
|
-
(
|
|
654
|
+
(_S = (_R = resolved.definition.defenses) == null ? void 0 : _R.condition_immunities) != null ? _S : [],
|
|
645
655
|
applied.defenses.condition_immunities,
|
|
646
656
|
featureEffects.condition_immunities
|
|
647
657
|
])
|
|
@@ -685,7 +695,7 @@ function recalc(resolved, registry) {
|
|
|
685
695
|
// untouched rows keep `critRange`/`attackNotes` ABSENT (not 20 / not []).
|
|
686
696
|
// crit-range: folded weapon crit threshold, only when an effect lowered it.
|
|
687
697
|
// attackNotes: reroll-damage / attack-rule captions, only when non-empty.
|
|
688
|
-
attacks: ((
|
|
698
|
+
attacks: ((_T = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _T : []).map((a) => {
|
|
689
699
|
var _a2;
|
|
690
700
|
const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses];
|
|
691
701
|
return {
|
|
@@ -696,10 +706,10 @@ function recalc(resolved, registry) {
|
|
|
696
706
|
...riders.length ? { damageRiders: riders } : {}
|
|
697
707
|
};
|
|
698
708
|
}),
|
|
699
|
-
equippedSlots: (
|
|
700
|
-
carriedWeight: (
|
|
701
|
-
attunementUsed: (
|
|
702
|
-
attunementLimit: (
|
|
709
|
+
equippedSlots: (_U = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _U : {},
|
|
710
|
+
carriedWeight: (_V = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _V : 0,
|
|
711
|
+
attunementUsed: (_W = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _W : 0,
|
|
712
|
+
attunementLimit: (_Y = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _Y : (_X = overrides.attunement_limit) != null ? _X : 3,
|
|
703
713
|
conditionEffects,
|
|
704
714
|
rollModifiers: featureEffects.rollModifiers
|
|
705
715
|
};
|
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
dedupeResolvedSpells,
|
|
10
10
|
resolveOriginFeat,
|
|
11
11
|
stripSlug
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-TNUFPIXI.js";
|
|
13
|
+
import "../chunk-7TEK5KK7.js";
|
|
14
|
+
import "../chunk-6IRYTM5V.js";
|
|
15
15
|
import "../chunk-5XUXXAQJ.js";
|
|
16
16
|
import "../chunk-JEYQU3JT.js";
|
|
17
17
|
import "../chunk-N6N74K6X.js";
|
package/dist/pc/pc.schema.d.ts
CHANGED
|
@@ -227,10 +227,14 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
227
227
|
ac: z.ZodOptional<z.ZodNumber>;
|
|
228
228
|
speed: z.ZodOptional<z.ZodNumber>;
|
|
229
229
|
initiative: z.ZodOptional<z.ZodNumber>;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
spellcasting_ability_by_class: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
231
|
+
str: "str";
|
|
232
|
+
dex: "dex";
|
|
233
|
+
con: "con";
|
|
234
|
+
int: "int";
|
|
235
|
+
wis: "wis";
|
|
236
|
+
cha: "cha";
|
|
237
|
+
}>>>;
|
|
234
238
|
spellcasting_ability: z.ZodOptional<z.ZodEnum<{
|
|
235
239
|
str: "str";
|
|
236
240
|
dex: "dex";
|
package/dist/pc/pc.schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Ability } from "@archivist-gg/dnd5e";
|
|
2
|
-
import type { KnownSpellEntry, ResolvedClass } from "./pc.types.js";
|
|
2
|
+
import type { CharacterOverrides, KnownSpellEntry, ResolvedClass } from "./pc.types.js";
|
|
3
3
|
import type { CasterType } from "@archivist-gg/dnd5e/class/class.types";
|
|
4
4
|
export interface SpellcastingProfile {
|
|
5
5
|
ability: Ability;
|
|
@@ -18,6 +18,10 @@ export interface SpellcastingProfile {
|
|
|
18
18
|
* non-casters. No hardcoded class knowledge — everything comes from the data.
|
|
19
19
|
*/
|
|
20
20
|
export declare function resolveSpellcasting(rc: ResolvedClass): SpellcastingProfile | null;
|
|
21
|
+
/** The ability a class actually casts with: a per-class override wins, else the
|
|
22
|
+
* data ability from resolveSpellcasting. `dataAbility` is non-nullable by
|
|
23
|
+
* contract: resolve caster-ness (a non-null SpellcastingProfile) BEFORE calling. */
|
|
24
|
+
export declare function effectiveSpellcastingAbility(classSlug: string, dataAbility: Ability, overrides: CharacterOverrides): Ability;
|
|
21
25
|
export interface NormalizedKnownSpell {
|
|
22
26
|
slug: string;
|
|
23
27
|
classSlug: string | null;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeSpellLimits,
|
|
3
3
|
deriveSpellSlots,
|
|
4
|
+
effectiveSpellcastingAbility,
|
|
4
5
|
normalizeKnownSpell,
|
|
5
6
|
resolveSpellcasting
|
|
6
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-6IRYTM5V.js";
|
|
7
8
|
import "../chunk-5XUXXAQJ.js";
|
|
8
9
|
import "../chunk-VTTA2ALZ.js";
|
|
9
10
|
import "../chunk-NAEPSZAM.js";
|
|
@@ -11,6 +12,7 @@ import "../chunk-WP2CX2JO.js";
|
|
|
11
12
|
export {
|
|
12
13
|
computeSpellLimits,
|
|
13
14
|
deriveSpellSlots,
|
|
15
|
+
effectiveSpellcastingAbility,
|
|
14
16
|
normalizeKnownSpell,
|
|
15
17
|
resolveSpellcasting
|
|
16
18
|
};
|
package/dist/pc/pc.types.d.ts
CHANGED
|
@@ -126,10 +126,7 @@ export interface CharacterOverrides {
|
|
|
126
126
|
ac?: number;
|
|
127
127
|
speed?: number;
|
|
128
128
|
initiative?: number;
|
|
129
|
-
|
|
130
|
-
saveDC?: number;
|
|
131
|
-
attackBonus?: number;
|
|
132
|
-
};
|
|
129
|
+
spellcasting_ability_by_class?: Partial<Record<string, Ability>>;
|
|
133
130
|
/** Character-level spellcasting ability for spells that carry no ability of
|
|
134
131
|
* their own (e.g. a Spell Scroll cast by a non-caster): the DC-ability fallback
|
|
135
132
|
* after a per-instance override and the character's own class ability. */
|
|
@@ -585,6 +582,7 @@ export interface SpellcastingClassInfo {
|
|
|
585
582
|
classSlug: string;
|
|
586
583
|
className: string;
|
|
587
584
|
ability: Ability;
|
|
585
|
+
defaultAbility: Ability;
|
|
588
586
|
saveDC: number;
|
|
589
587
|
attackBonus: number;
|
|
590
588
|
casterType: "full" | "half" | "third" | "pact";
|
package/dist/types/choice.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import type { FeatureEffect } from "./feature-effect.js";
|
|
|
3
3
|
export type Ability = keyof Abilities;
|
|
4
4
|
export type SkillSlug = "acrobatics" | "animal-handling" | "arcana" | "athletics" | "deception" | "history" | "insight" | "intimidation" | "investigation" | "medicine" | "nature" | "perception" | "performance" | "persuasion" | "religion" | "sleight-of-hand" | "stealth" | "survival";
|
|
5
5
|
export declare const ALL_SKILL_SLUGS: SkillSlug[];
|
|
6
|
+
/** The SRD language set: 8 standard + 8 exotic. Authoritative and reused as
|
|
7
|
+
* KNOWN_LANGUAGES by the proficiency aggregate; slugs are edition-agnostic. */
|
|
8
|
+
export declare const STANDARD_LANGUAGES: string[];
|
|
9
|
+
export declare const EXOTIC_LANGUAGES: string[];
|
|
10
|
+
export declare const ALL_LANGUAGES: string[];
|
|
6
11
|
export type FeatCategory = "origin" | "general" | "fighting-style" | "epic-boon";
|
|
7
12
|
/** Closed, enumerated registry filter — YAML can never express a query the
|
|
8
13
|
* engine would apply unsafely. `"self"` resolves against the owning
|
package/dist/types/choice.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ALL_LANGUAGES,
|
|
3
|
+
ALL_SKILL_SLUGS,
|
|
4
|
+
EXOTIC_LANGUAGES,
|
|
5
|
+
STANDARD_LANGUAGES
|
|
6
|
+
} from "../chunk-7TEK5KK7.js";
|
|
4
7
|
export {
|
|
5
|
-
|
|
8
|
+
ALL_LANGUAGES,
|
|
9
|
+
ALL_SKILL_SLUGS,
|
|
10
|
+
EXOTIC_LANGUAGES,
|
|
11
|
+
STANDARD_LANGUAGES
|
|
6
12
|
};
|
package/package.json
CHANGED
package/dist/chunk-BH6AMZVY.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// src/types/choice.ts
|
|
2
|
-
var ALL_SKILL_SLUGS = [
|
|
3
|
-
"acrobatics",
|
|
4
|
-
"animal-handling",
|
|
5
|
-
"arcana",
|
|
6
|
-
"athletics",
|
|
7
|
-
"deception",
|
|
8
|
-
"history",
|
|
9
|
-
"insight",
|
|
10
|
-
"intimidation",
|
|
11
|
-
"investigation",
|
|
12
|
-
"medicine",
|
|
13
|
-
"nature",
|
|
14
|
-
"perception",
|
|
15
|
-
"performance",
|
|
16
|
-
"persuasion",
|
|
17
|
-
"religion",
|
|
18
|
-
"sleight-of-hand",
|
|
19
|
-
"stealth",
|
|
20
|
-
"survival"
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
ALL_SKILL_SLUGS
|
|
25
|
-
};
|