@archivist-gg/dnd5e 0.3.1 → 0.3.5
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/LICENSES/SRD.md +25 -6
- package/dist/armor/armor.codec.js +4 -3
- package/dist/armor/armor.parser.js +3 -2
- package/dist/armor/armor.schema.d.ts +4 -0
- package/dist/armor/armor.schema.js +2 -1
- package/dist/armor/armor.types.d.ts +8 -0
- package/dist/background/background.codec.js +7 -6
- package/dist/background/background.parser.js +6 -5
- package/dist/background/background.schema.d.ts +26 -0
- package/dist/background/background.schema.js +5 -4
- package/dist/background/background.types.d.ts +22 -0
- package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
- package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
- package/dist/chunk-2FRUSVZS.js +489 -0
- package/dist/chunk-2VDTW7QO.js +1580 -0
- package/dist/{chunk-ZZGEVJKX.js → chunk-3JOTQW7A.js} +1 -1
- package/dist/{chunk-5ZBE4CWV.js → chunk-3PZHBLFG.js} +1 -1
- package/dist/chunk-4U55VNC7.js +22 -0
- package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
- package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
- package/dist/{chunk-42Y5IJKT.js → chunk-5RKLL2AD.js} +5 -1
- package/dist/{chunk-SE7AZDR3.js → chunk-63XQXPZL.js} +29 -3
- package/dist/{chunk-4F6AIZ36.js → chunk-6BFWZW6T.js} +1 -1
- package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
- package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
- package/dist/chunk-6X2NV665.js +33 -0
- package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
- package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
- package/dist/{chunk-TLYDBT5F.js → chunk-CGRLQ34U.js} +64 -7
- package/dist/chunk-CJYCVNW2.js +7 -0
- package/dist/{chunk-XLSVNUTK.js → chunk-CV5XDJKU.js} +1 -1
- package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
- package/dist/{chunk-6IRYTM5V.js → chunk-DPUJDOKV.js} +119 -28
- package/dist/{chunk-GE4TLPWM.js → chunk-EHDATXP7.js} +1 -1
- package/dist/chunk-EVMUJYUD.js +195 -0
- package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
- package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
- package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
- package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
- package/dist/chunk-IUAAXXNO.js +58 -0
- package/dist/{chunk-NXSWH3AE.js → chunk-IWRVOCT5.js} +1 -1
- package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
- package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
- package/dist/{chunk-XTIQWSFM.js → chunk-KADJZGZY.js} +1 -1
- package/dist/{chunk-L7E2UT5A.js → chunk-KK33PIDN.js} +5 -1
- package/dist/chunk-KPEJMNRD.js +302 -0
- package/dist/chunk-KU3YLF6D.js +106 -0
- package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
- package/dist/chunk-LVQLWRCU.js +15 -0
- package/dist/chunk-MI7P3NX3.js +161 -0
- package/dist/{chunk-PHQRGDRQ.js → chunk-N3A5ICBO.js} +5 -1
- package/dist/chunk-O4SRD3J5.js +165 -0
- package/dist/chunk-OAXWSVJB.js +81 -0
- package/dist/chunk-OZP6JFGT.js +162 -0
- package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
- package/dist/chunk-PP2UHLBA.js +50 -0
- package/dist/chunk-PVCEA4HZ.js +6 -0
- package/dist/{chunk-RSDRMH54.js → chunk-RF4TYCA2.js} +1 -1
- package/dist/chunk-RLGQ5PZZ.js +16 -0
- package/dist/chunk-RVXC6ZHY.js +89 -0
- package/dist/chunk-S7REMWW4.js +21 -0
- package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
- package/dist/chunk-TOM66P2P.js +38 -0
- package/dist/chunk-UA5KS2PL.js +26 -0
- package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
- package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
- package/dist/{chunk-BIK4DFWK.js → chunk-ULCQ73LA.js} +1 -1
- package/dist/{chunk-2BWAID3Y.js → chunk-UMWIPLLM.js} +29 -3
- package/dist/chunk-UQ3ZFCWD.js +178 -0
- package/dist/chunk-UXPGW4TI.js +101 -0
- package/dist/chunk-V2MJE6NC.js +133 -0
- package/dist/{chunk-D3CLOBE3.js → chunk-V373TRJE.js} +48 -10
- package/dist/chunk-VQAXTIBW.js +100 -0
- package/dist/chunk-W74BCA7V.js +159 -0
- package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
- package/dist/{chunk-MDEJHMKK.js → chunk-WHVLNFTG.js} +26 -5
- package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
- package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
- package/dist/chunk-X3D6LXUU.js +185 -0
- package/dist/chunk-XJ2F2WO6.js +8 -0
- package/dist/{chunk-73HOFQQ5.js → chunk-Y4AGLCY6.js} +1 -1
- package/dist/chunk-YBLDE5CG.js +42 -0
- package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
- package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
- package/dist/class/class.codec.js +12 -9
- package/dist/class/class.parser.js +11 -8
- package/dist/class/class.schema.d.ts +55 -3
- package/dist/class/class.schema.js +9 -7
- package/dist/class/class.types.d.ts +48 -3
- package/dist/condition/condition.codec.d.ts +9 -0
- package/dist/condition/condition.entity-type.d.ts +2 -0
- package/dist/condition/condition.parser.d.ts +13 -0
- package/dist/condition/condition.parser.js +7 -0
- package/dist/condition/condition.schema.d.ts +29 -0
- package/dist/condition/condition.types.d.ts +15 -0
- package/dist/condition/condition.types.js +0 -0
- package/dist/dnd/constants.d.ts +22 -0
- package/dist/dnd/constants.js +9 -3
- package/dist/dnd/formula-tags.js +2 -2
- package/dist/dnd/math.d.ts +26 -0
- package/dist/dnd/math.js +12 -2
- package/dist/dnd/prose-tags.js +1 -1
- package/dist/dnd/resource-formula.d.ts +36 -10
- package/dist/dnd/resource-formula.js +10 -155
- package/dist/dnd/srd-tag-converter.js +3 -3
- package/dist/dnd/tag-grammar.js +1 -1
- package/dist/dnd/warn-once.d.ts +2 -0
- package/dist/dnd/warn-once.js +8 -0
- package/dist/entities/base-item-resolver.js +2 -2
- package/dist/entities/slug.d.ts +13 -0
- package/dist/entities/slug.js +5 -3
- package/dist/entities/wikilink-display.d.ts +3 -0
- package/dist/entities/wikilink-display.js +10 -0
- package/dist/feat/feat.category-codes.d.ts +32 -0
- package/dist/feat/feat.category-codes.js +14 -0
- package/dist/feat/feat.codec.js +7 -5
- package/dist/feat/feat.parser.js +6 -4
- package/dist/feat/feat.schema.d.ts +239 -0
- package/dist/feat/feat.schema.js +5 -3
- package/dist/feat/feat.types.d.ts +37 -1
- package/dist/index.js +2033 -6907
- package/dist/item/item.codec.js +4 -3
- package/dist/item/item.enrichment.js +4 -4
- package/dist/item/item.parser.js +3 -2
- package/dist/item/item.schema.d.ts +69 -3
- package/dist/item/item.schema.js +2 -1
- package/dist/item/item.types.d.ts +69 -3
- package/dist/monster/monster.codec.d.ts +7 -6
- package/dist/monster/monster.enrichment.js +4 -4
- package/dist/monster/monster.format.d.ts +135 -0
- package/dist/monster/monster.format.js +78 -0
- package/dist/monster/monster.parser.d.ts +6 -1
- package/dist/monster/monster.parser.js +10 -1
- package/dist/monster/monster.schema.d.ts +369 -0
- package/dist/monster/monster.schema.js +34 -0
- package/dist/monster/monster.types.d.ts +200 -14
- package/dist/optional-feature/optional-feature.codec.js +6 -5
- package/dist/optional-feature/optional-feature.parser.js +5 -4
- package/dist/optional-feature/optional-feature.schema.d.ts +185 -0
- package/dist/optional-feature/optional-feature.schema.js +4 -3
- package/dist/pack.d.ts +1 -1
- package/dist/pc/conditions.constants.d.ts +0 -1
- package/dist/pc/conditions.constants.js +1 -3
- package/dist/pc/decision-recognizer.js +1 -1
- package/dist/pc/pc.additional-spells.d.ts +47 -0
- package/dist/pc/pc.additional-spells.js +23 -0
- package/dist/pc/pc.asi-flatten.d.ts +18 -0
- package/dist/pc/pc.decision-engine.d.ts +105 -17
- package/dist/pc/pc.decision-engine.js +28 -12
- package/dist/pc/pc.defense-normalize.d.ts +11 -0
- package/dist/pc/pc.defense-normalize.js +6 -0
- package/dist/pc/pc.equipment.d.ts +31 -2
- package/dist/pc/pc.equipment.js +12 -8
- package/dist/pc/pc.feature-effects.d.ts +234 -11
- package/dist/pc/pc.feature-effects.js +21 -5
- package/dist/pc/pc.parser.js +2 -2
- package/dist/pc/pc.pools.d.ts +11 -3
- package/dist/pc/pc.pools.js +9 -13
- package/dist/pc/pc.proficiencies.d.ts +54 -29
- package/dist/pc/pc.proficiencies.js +74 -95
- package/dist/pc/pc.proficiency-grants.d.ts +58 -0
- package/dist/pc/pc.proficiency-normalize.d.ts +24 -0
- package/dist/pc/pc.proficiency-normalize.js +12 -0
- package/dist/pc/pc.proficiency-query.d.ts +13 -0
- package/dist/pc/pc.proficiency-query.js +1 -1
- package/dist/pc/pc.recalc.d.ts +69 -14
- package/dist/pc/pc.recalc.js +261 -122
- package/dist/pc/pc.resolver.d.ts +34 -8
- package/dist/pc/pc.resolver.js +27 -12
- package/dist/pc/pc.resource-seed.d.ts +3 -2
- package/dist/pc/pc.resource-seed.js +19 -17
- package/dist/pc/pc.resources.d.ts +87 -0
- package/dist/pc/pc.resources.js +21 -0
- package/dist/pc/pc.rest.d.ts +10 -1
- package/dist/pc/pc.rest.js +66 -12
- package/dist/pc/pc.schema.d.ts +139 -3
- package/dist/pc/pc.schema.js +4 -2
- package/dist/pc/pc.slotting.js +3 -3
- package/dist/pc/pc.spellcasting.d.ts +75 -6
- package/dist/pc/pc.spellcasting.js +16 -6
- package/dist/pc/pc.table-column.d.ts +23 -0
- package/dist/pc/pc.table-column.js +13 -3
- package/dist/pc/pc.types.d.ts +251 -12
- package/dist/pc/pool-layout.d.ts +47 -0
- package/dist/pc/pool-layout.js +16 -0
- package/dist/pc/roll-scope.d.ts +2 -0
- package/dist/pc/roll-scope.js +8 -0
- package/dist/pc/roll-tag-labels.d.ts +40 -0
- package/dist/pc/roll-tag-labels.js +17 -0
- package/dist/pc/spell-source.d.ts +21 -0
- package/dist/pc/spell-source.js +13 -0
- package/dist/race/race.codec.js +9 -7
- package/dist/race/race.parser.js +8 -6
- package/dist/race/race.schema.d.ts +51 -1
- package/dist/race/race.schema.js +8 -5
- package/dist/race/race.structural.d.ts +7 -0
- package/dist/race/race.structural.js +6 -0
- package/dist/race/race.types.d.ts +20 -0
- package/dist/schemas/attack-schema.d.ts +5 -0
- package/dist/schemas/caster-type-schema.d.ts +14 -0
- package/dist/schemas/caster-type-schema.js +6 -0
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/entity-extras-schema.d.ts +53 -0
- package/dist/schemas/entity-extras-schema.js +10 -0
- package/dist/schemas/equipment-grant-schema.d.ts +2 -0
- package/dist/schemas/equipment-grant-schema.js +1 -1
- package/dist/schemas/feature-alias.d.ts +34 -0
- package/dist/schemas/feature-effect-schema.d.ts +133 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.d.ts +8 -0
- package/dist/schemas/feature-schema.js +6 -4
- package/dist/schemas/resource-schema.d.ts +43 -0
- package/dist/schemas/resource-schema.js +1 -1
- package/dist/schemas/selection-pool-schema.d.ts +2 -0
- package/dist/schemas/selection-pool-schema.js +1 -1
- package/dist/spell/spell.access.js +23 -3
- package/dist/spell/spell.codec.js +4 -3
- package/dist/spell/spell.enrichment.js +4 -4
- package/dist/spell/spell.parser.d.ts +30 -0
- package/dist/spell/spell.parser.js +9 -2
- package/dist/spell/spell.scaling.d.ts +27 -6
- package/dist/spell/spell.scaling.js +25 -6
- package/dist/spell/spell.schema.d.ts +44 -2
- package/dist/spell/spell.schema.js +2 -1
- package/dist/spell/spell.types.d.ts +14 -0
- package/dist/subclass/subclass.codec.d.ts +1 -1
- package/dist/subclass/subclass.codec.js +11 -8
- package/dist/subclass/subclass.parser.js +10 -7
- package/dist/subclass/subclass.schema.d.ts +54 -7
- package/dist/subclass/subclass.schema.js +8 -6
- package/dist/subclass/subclass.types.d.ts +20 -2
- package/dist/types/choice.d.ts +53 -2
- package/dist/types/choice.js +13 -1
- package/dist/types/equipment-grant.d.ts +8 -1
- package/dist/types/feature-effect.d.ts +85 -23
- package/dist/types/feature.d.ts +70 -1
- package/dist/types/optional-feature.types.d.ts +28 -0
- package/dist/types/resource.d.ts +21 -1
- package/dist/types/selection-pool.d.ts +17 -2
- package/dist/weapon/weapon.classify.js +2 -2
- package/dist/weapon/weapon.codec.js +4 -3
- package/dist/weapon/weapon.parser.js +3 -2
- package/dist/weapon/weapon.schema.d.ts +4 -0
- package/dist/weapon/weapon.schema.js +2 -1
- package/dist/weapon/weapon.types.d.ts +8 -0
- package/package.json +2 -2
- package/dist/chunk-5XUXXAQJ.js +0 -30
- package/dist/chunk-7P65Q426.js +0 -158
- package/dist/chunk-7TEK5KK7.js +0 -49
- package/dist/chunk-AIRFC5NQ.js +0 -143
- package/dist/chunk-CZPMTQOY.js +0 -68
- package/dist/chunk-N2JE7BWL.js +0 -81
- package/dist/chunk-NXR3BD2V.js +0 -90
- package/dist/chunk-O5EYMKFH.js +0 -6
- package/dist/chunk-Q5K6LWBZ.js +0 -45
- package/dist/chunk-TNUFPIXI.js +0 -1110
- package/dist/chunk-TZK36BU7.js +0 -38
- package/dist/chunk-W7HWMMBF.js +0 -46
- package/dist/chunk-Y4I74YEG.js +0 -33
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/schemas/feature-alias.ts
|
|
2
|
+
function aliasFeatureActionCost(f) {
|
|
3
|
+
if (f.action === void 0 && typeof f.action_cost === "string") f.action = f.action_cost;
|
|
4
|
+
}
|
|
5
|
+
function aliasFeatureListActionCost(list) {
|
|
6
|
+
if (Array.isArray(list)) {
|
|
7
|
+
for (const f of list) if (f && typeof f === "object") aliasFeatureActionCost(f);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function aliasFeaturesByLevelActionCost(byLevel) {
|
|
11
|
+
if (byLevel && typeof byLevel === "object")
|
|
12
|
+
for (const list of Object.values(byLevel)) aliasFeatureListActionCost(list);
|
|
13
|
+
}
|
|
14
|
+
function withResolvedActionCost(f) {
|
|
15
|
+
return f.action === void 0 && typeof f.action_cost === "string" ? { ...f, action: f.action_cost } : f;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
aliasFeatureListActionCost,
|
|
20
|
+
aliasFeaturesByLevelActionCost,
|
|
21
|
+
withResolvedActionCost
|
|
22
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
armorEntitySchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JC5UNIVM.js";
|
|
4
4
|
|
|
5
5
|
// src/armor/armor.parser.ts
|
|
6
6
|
import { parseYaml } from "@archivist-gg/core";
|
|
@@ -18,12 +18,25 @@ var KNOWN_KEYS = /* @__PURE__ */ new Set([
|
|
|
18
18
|
"page",
|
|
19
19
|
"edition",
|
|
20
20
|
"entries",
|
|
21
|
-
"raw"
|
|
21
|
+
"raw",
|
|
22
|
+
// Root extras declared on armorEntitySchema (spec §5). The schema declaring them is NOT
|
|
23
|
+
// enough: this set is the second, independent gate — a key missing here is copied into
|
|
24
|
+
// `raw` as well, so the two lists must move together.
|
|
25
|
+
"rendering_hint",
|
|
26
|
+
"has_fluff",
|
|
27
|
+
"has_fluff_images",
|
|
28
|
+
"image",
|
|
29
|
+
// The alias is a KNOWN key so it is never copied into `raw` alongside the mapped
|
|
30
|
+
// `strength_requirement` — that duplicate is the census row this fix empties.
|
|
31
|
+
"strength_required"
|
|
22
32
|
]);
|
|
23
33
|
function parseArmor(source) {
|
|
24
34
|
var _a;
|
|
25
35
|
const raw = parseYaml(source, ["name", "slug", "category", "ac"]);
|
|
26
36
|
if (!raw.success) return raw;
|
|
37
|
+
if (raw.data.strength_requirement === void 0 && typeof raw.data.strength_required === "number") {
|
|
38
|
+
raw.data.strength_requirement = raw.data.strength_required;
|
|
39
|
+
}
|
|
27
40
|
const result = armorEntitySchema.safeParse(raw.data);
|
|
28
41
|
if (!result.success) {
|
|
29
42
|
return { success: false, error: `armor schema validation failed: ${result.error.message}` };
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aliasFeaturesByLevelActionCost
|
|
3
|
+
} from "./chunk-4U55VNC7.js";
|
|
1
4
|
import {
|
|
2
5
|
classEntitySchema
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CGRLQ34U.js";
|
|
4
7
|
|
|
5
8
|
// src/class/class.parser.ts
|
|
6
9
|
import { parseYaml } from "@archivist-gg/core";
|
|
7
10
|
function parseClass(source) {
|
|
8
11
|
const raw = parseYaml(source, ["name", "slug"]);
|
|
9
12
|
if (!raw.success) return raw;
|
|
13
|
+
aliasFeaturesByLevelActionCost(raw.data.features_by_level);
|
|
10
14
|
const result = classEntitySchema.safeParse({ edition: "2014", ...raw.data });
|
|
11
15
|
if (!result.success) {
|
|
12
16
|
return { success: false, error: `class schema validation failed: ${result.error.message}` };
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
startingEquipmentEntrySchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IN4M4X7P.js";
|
|
4
4
|
import {
|
|
5
5
|
choiceSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IWRVOCT5.js";
|
|
7
|
+
import {
|
|
8
|
+
additionalSpellsEntrySchema,
|
|
9
|
+
imageField
|
|
10
|
+
} from "./chunk-UA5KS2PL.js";
|
|
7
11
|
|
|
8
12
|
// src/background/background.schema.ts
|
|
9
13
|
import { z } from "zod";
|
|
@@ -75,7 +79,29 @@ var backgroundEntitySchema = z.object({
|
|
|
75
79
|
}).nullable(),
|
|
76
80
|
origin_feat: z.string().regex(wikilinkRegex).nullable(),
|
|
77
81
|
suggested_characteristics: suggestedCharSchema.nullable(),
|
|
78
|
-
choices: z.array(choiceSchema).optional()
|
|
82
|
+
choices: z.array(choiceSchema).optional(),
|
|
83
|
+
rendering_hint: z.string().optional(),
|
|
84
|
+
// 175
|
|
85
|
+
has_fluff_images: z.boolean().optional(),
|
|
86
|
+
// 87
|
|
87
|
+
tables: z.array(z.object({
|
|
88
|
+
// 88 tables / 67 docs; key-sets EXACT (finding 6)
|
|
89
|
+
name: z.string().min(1),
|
|
90
|
+
dice: z.string().min(1),
|
|
91
|
+
rows: z.array(z.object({ roll: z.string(), text: z.string() }))
|
|
92
|
+
})).optional(),
|
|
93
|
+
additional_spells: z.array(additionalSpellsEntrySchema).optional(),
|
|
94
|
+
// 15
|
|
95
|
+
prerequisites: z.array(z.object({
|
|
96
|
+
// 4 docs; kind CLOSED AT THE EMITTER
|
|
97
|
+
kind: z.literal("campaign"),
|
|
98
|
+
slug: z.string().min(1)
|
|
99
|
+
// (background-mapper.ts pushes
|
|
100
|
+
})).optional(),
|
|
101
|
+
// {kind:"campaign", slug} literally — finding 24)
|
|
102
|
+
// The one-arm union STAYS (§2.6 adjudication): it is closed by CONSTRUCTION at the converter's
|
|
103
|
+
// only push site, and a future kind turns into a visible census REFUSAL — the correct loud failure.
|
|
104
|
+
image: imageField
|
|
79
105
|
});
|
|
80
106
|
|
|
81
107
|
export {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
convertDescToTags,
|
|
3
3
|
detectSpellcastingAbility
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DEEHHLAP.js";
|
|
5
5
|
import {
|
|
6
6
|
abilityModifier
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PDJSUH24.js";
|
|
8
8
|
|
|
9
9
|
// src/monster/monster.enrichment.ts
|
|
10
10
|
import { toStringSafe } from "@archivist-gg/core";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
imageField
|
|
3
|
+
} from "./chunk-UA5KS2PL.js";
|
|
4
|
+
|
|
5
|
+
// src/condition/condition.parser.ts
|
|
6
|
+
import { parseYaml } from "@archivist-gg/core";
|
|
7
|
+
|
|
8
|
+
// src/condition/condition.schema.ts
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
var conditionEntitySchema = z.object({
|
|
11
|
+
slug: z.string().min(1),
|
|
12
|
+
name: z.string().min(1),
|
|
13
|
+
edition: z.enum(["2014", "2024"]),
|
|
14
|
+
source: z.string().min(1),
|
|
15
|
+
description: z.string(),
|
|
16
|
+
has_fluff_images: z.boolean().optional(),
|
|
17
|
+
image: imageField
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// src/condition/condition.parser.ts
|
|
21
|
+
function parseCondition(source) {
|
|
22
|
+
const raw = parseYaml(source, ["name", "slug"]);
|
|
23
|
+
if (!raw.success) return raw;
|
|
24
|
+
const result = conditionEntitySchema.safeParse({ edition: "2014", ...raw.data });
|
|
25
|
+
if (!result.success) {
|
|
26
|
+
return { success: false, error: `condition schema validation failed: ${result.error.message}` };
|
|
27
|
+
}
|
|
28
|
+
return { success: true, data: result.data };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
parseCondition
|
|
33
|
+
};
|
|
@@ -7,8 +7,15 @@ function bareEntitySlug(slug) {
|
|
|
7
7
|
const p = slug.split("_");
|
|
8
8
|
return p.length >= 3 ? p.slice(2).join("_") : p[p.length - 1];
|
|
9
9
|
}
|
|
10
|
+
function wikilinkTailSlug(link) {
|
|
11
|
+
var _a;
|
|
12
|
+
const inner = link.replace(/^\[\[/, "").replace(/\]\]$/, "");
|
|
13
|
+
const tail = (_a = inner.split("/").pop()) != null ? _a : inner;
|
|
14
|
+
return slugify(tail);
|
|
15
|
+
}
|
|
10
16
|
|
|
11
17
|
export {
|
|
12
18
|
slugify,
|
|
13
|
-
bareEntitySlug
|
|
19
|
+
bareEntitySlug,
|
|
20
|
+
wikilinkTailSlug
|
|
14
21
|
};
|
|
@@ -2,17 +2,28 @@ import {
|
|
|
2
2
|
poolGrantSchema,
|
|
3
3
|
selectionPoolSchema,
|
|
4
4
|
tabDeclSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-23LZLBJK.js";
|
|
6
|
+
import {
|
|
7
|
+
casterTypeEnum
|
|
8
|
+
} from "./chunk-CJYCVNW2.js";
|
|
6
9
|
import {
|
|
7
10
|
featureSchema
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-W74BCA7V.js";
|
|
9
12
|
import {
|
|
10
13
|
resourceSchema
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YLL2QXY2.js";
|
|
12
15
|
import {
|
|
13
16
|
startingEquipmentEntrySchema,
|
|
14
17
|
startingGoldSchema
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-IN4M4X7P.js";
|
|
19
|
+
import {
|
|
20
|
+
choiceSchema
|
|
21
|
+
} from "./chunk-IWRVOCT5.js";
|
|
22
|
+
import {
|
|
23
|
+
additionalSpellsEntrySchema,
|
|
24
|
+
imageField,
|
|
25
|
+
progressionSchema
|
|
26
|
+
} from "./chunk-UA5KS2PL.js";
|
|
16
27
|
|
|
17
28
|
// src/class/class.schema.ts
|
|
18
29
|
import { z } from "zod";
|
|
@@ -67,7 +78,6 @@ var toolProficiencySchema = z.object({
|
|
|
67
78
|
}, {
|
|
68
79
|
message: "tool proficiency must declare fixed or choice"
|
|
69
80
|
});
|
|
70
|
-
var casterTypeEnum = z.enum(["full", "half", "third", "pact"]);
|
|
71
81
|
var spellcastingSchema = z.object({
|
|
72
82
|
caster_type: casterTypeEnum,
|
|
73
83
|
ability: abilityEnum,
|
|
@@ -75,7 +85,16 @@ var spellcastingSchema = z.object({
|
|
|
75
85
|
spell_list: z.string().min(1)
|
|
76
86
|
});
|
|
77
87
|
var weaponMasterySchema = z.object({
|
|
78
|
-
|
|
88
|
+
// §2.7's ONE deliberate relaxation, and the phase's only non-additive edit. Measured: `starting_count`
|
|
89
|
+
// has ZERO read sites in either repo, all 24 SRD class records are `weapon_mastery: null`, and the
|
|
90
|
+
// converter population is zero too (26 of 28 class docs null; both object carriers DO carry the count).
|
|
91
|
+
// It exists so the converter can re-emit a countless mastery object later. R4-G5 did NOT make it read: §6 takes
|
|
92
|
+
// the count from the class TABLE COLUMN instead (`COUNT_COLUMNS` in `pc.table-column.ts`), because the column
|
|
93
|
+
// is the truth on BOTH corpora, and `count.column` on the choice itself is booked to the G7 converter handoff.
|
|
94
|
+
// `starting_count` therefore still has ZERO read sites.
|
|
95
|
+
// A THREE-declaration edit (finding 11): here, `class.types.ts`, and the generator's COPIED
|
|
96
|
+
// `interface WeaponMasteryConfig` in tools/srd-canonical/merger-rules/class-merge.ts.
|
|
97
|
+
starting_count: z.number().int().nonnegative().optional(),
|
|
79
98
|
scaling: z.record(z.string(), z.number().int().nonnegative()).optional()
|
|
80
99
|
});
|
|
81
100
|
var classTableRowSchema = z.object({
|
|
@@ -101,6 +120,10 @@ var classEntitySchema = z.object({
|
|
|
101
120
|
count: z.number().int().positive(),
|
|
102
121
|
from: z.array(skillEnum).nonempty()
|
|
103
122
|
}),
|
|
123
|
+
// Zod strips unknown keys by default, so without this declaration an authored
|
|
124
|
+
// `choices:` block is silently deleted by `parseClass`. Same spelling as
|
|
125
|
+
// `raceEntitySchema` / `backgroundEntitySchema`.
|
|
126
|
+
choices: z.array(choiceSchema).optional(),
|
|
104
127
|
starting_equipment: z.array(startingEquipmentEntrySchema),
|
|
105
128
|
starting_gold: startingGoldSchema.optional(),
|
|
106
129
|
spellcasting: spellcastingSchema.nullable(),
|
|
@@ -113,7 +136,41 @@ var classEntitySchema = z.object({
|
|
|
113
136
|
resources: z.array(resourceSchema),
|
|
114
137
|
selection_pools: z.array(selectionPoolSchema).optional(),
|
|
115
138
|
pool_grants: z.array(poolGrantSchema).optional(),
|
|
116
|
-
tabs: z.array(tabDeclSchema).optional()
|
|
139
|
+
tabs: z.array(tabDeclSchema).optional(),
|
|
140
|
+
rendering_hint: z.string().optional(),
|
|
141
|
+
// 28
|
|
142
|
+
has_fluff: z.boolean().optional(),
|
|
143
|
+
// 28
|
|
144
|
+
has_fluff_images: z.boolean().optional(),
|
|
145
|
+
// 27
|
|
146
|
+
table_col_labels: z.array(z.string().min(1)).optional(),
|
|
147
|
+
// 28
|
|
148
|
+
starting_equipment_additional_from_background: z.boolean().optional(),
|
|
149
|
+
// 28
|
|
150
|
+
multiclassing: z.unknown().optional(),
|
|
151
|
+
// FOUR arities measured incl. {} ×3; free-form 5etools keys
|
|
152
|
+
// ("thieves' tools", requirements.or[].{dex,str}) — Q1 ruling
|
|
153
|
+
cantrip_progression: z.array(z.number()).optional(),
|
|
154
|
+
// 15
|
|
155
|
+
prepared_spells: z.string().min(1).optional(),
|
|
156
|
+
// formula string "<$level$> / 2 + <$int_mod$>"
|
|
157
|
+
prepared_spells_change: z.string().min(1).optional(),
|
|
158
|
+
// "restLong"
|
|
159
|
+
prepared_spells_progression: z.array(z.number()).optional(),
|
|
160
|
+
spells_known_progression: z.array(z.number()).optional(),
|
|
161
|
+
spells_known_progression_fixed: z.array(z.number()).optional(),
|
|
162
|
+
spells_known_progression_fixed_allow_lower_level: z.boolean().optional(),
|
|
163
|
+
// ⚠️ BOOLEAN (finding 1)
|
|
164
|
+
spells_known_progression_fixed_by_level: z.record(z.string(), z.record(z.string(), z.number())).optional(),
|
|
165
|
+
// ⚠️ two-deep record (finding 1)
|
|
166
|
+
feat_progression: z.array(progressionSchema).optional(),
|
|
167
|
+
// 13
|
|
168
|
+
optionalfeature_progression: z.array(progressionSchema).optional(),
|
|
169
|
+
// 9 carriers; the ARRAY
|
|
170
|
+
// progression arm rides 4 of them
|
|
171
|
+
additional_spells: z.array(additionalSpellsEntrySchema).optional(),
|
|
172
|
+
// 7
|
|
173
|
+
image: imageField
|
|
117
174
|
});
|
|
118
175
|
|
|
119
176
|
export {
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readTableColumn
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IUAAXXNO.js";
|
|
4
4
|
import {
|
|
5
|
-
bareSlug
|
|
5
|
+
bareSlug,
|
|
6
|
+
baseClassName
|
|
6
7
|
} from "./chunk-VTTA2ALZ.js";
|
|
7
8
|
import {
|
|
8
9
|
abilityModifier
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PDJSUH24.js";
|
|
10
11
|
|
|
11
12
|
// src/pc/pc.spellcasting.ts
|
|
13
|
+
function hasPreparedColumn(table) {
|
|
14
|
+
return Object.values(table).some((row) => PREPARED_COLUMNS.some((k) => {
|
|
15
|
+
var _a;
|
|
16
|
+
return ((_a = row == null ? void 0 : row.columns) == null ? void 0 : _a[k]) !== void 0;
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
12
19
|
function resolveSpellcasting(rc) {
|
|
13
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
20
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
14
21
|
const sub = (_b = (_a = rc.subclass) == null ? void 0 : _a.spellcasting) != null ? _b : null;
|
|
15
22
|
const cls = (_d = (_c = rc.entity) == null ? void 0 : _c.spellcasting) != null ? _d : null;
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
spellList: sc.spell_list,
|
|
24
|
-
table
|
|
25
|
-
};
|
|
23
|
+
const casterType = (_f = (_e = sub == null ? void 0 : sub.caster_type) != null ? _e : cls == null ? void 0 : cls.caster_type) != null ? _f : null;
|
|
24
|
+
const ability = (_h = (_g = sub == null ? void 0 : sub.ability) != null ? _g : cls == null ? void 0 : cls.ability) != null ? _h : null;
|
|
25
|
+
if (!casterType || !ability) return null;
|
|
26
|
+
const table = (_l = (_k = (sub == null ? void 0 : sub.caster_type) ? (_i = rc.subclass) == null ? void 0 : _i.table : void 0) != null ? _k : (_j = rc.entity) == null ? void 0 : _j.table) != null ? _l : {};
|
|
27
|
+
const preparation = (_n = (_m = sub == null ? void 0 : sub.preparation) != null ? _m : cls == null ? void 0 : cls.preparation) != null ? _n : hasPreparedColumn(table) ? "prepared" : "known";
|
|
28
|
+
const spellList = (_p = (_o = sub == null ? void 0 : sub.spell_list) != null ? _o : cls == null ? void 0 : cls.spell_list) != null ? _p : null;
|
|
29
|
+
return { ability, casterType, preparation, spellList, table };
|
|
26
30
|
}
|
|
27
31
|
function effectiveSpellcastingAbility(classSlug, dataAbility, overrides) {
|
|
28
32
|
var _a, _b;
|
|
@@ -41,6 +45,43 @@ function normalizeKnownSpell(entry) {
|
|
|
41
45
|
alwaysPrepared: (_b = entry.always_prepared) != null ? _b : false
|
|
42
46
|
};
|
|
43
47
|
}
|
|
48
|
+
function firstListedCasterClass(spellClasses, casterClassSlugs) {
|
|
49
|
+
var _a;
|
|
50
|
+
if (!Array.isArray(spellClasses) || spellClasses.length === 0) return null;
|
|
51
|
+
const listed = new Set(spellClasses.map((c) => baseClassName(String(c))));
|
|
52
|
+
return (_a = casterClassSlugs.find((slug) => listed.has(baseClassName(slug)))) != null ? _a : null;
|
|
53
|
+
}
|
|
54
|
+
var LISTED_CLASS_NAMES = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
var NO_NAMES = /* @__PURE__ */ new Set();
|
|
56
|
+
function listedSpellClassNames(registry, compendium) {
|
|
57
|
+
var _a;
|
|
58
|
+
const count = registry.count();
|
|
59
|
+
let cached = LISTED_CLASS_NAMES.get(registry);
|
|
60
|
+
if (!cached || cached.count !== count) {
|
|
61
|
+
const byCompendium = /* @__PURE__ */ new Map();
|
|
62
|
+
for (const e of registry.search("", "spell", Number.POSITIVE_INFINITY)) {
|
|
63
|
+
const classes = e.data.classes;
|
|
64
|
+
if (!Array.isArray(classes)) continue;
|
|
65
|
+
let names = byCompendium.get(e.compendium);
|
|
66
|
+
if (!names) byCompendium.set(e.compendium, names = /* @__PURE__ */ new Set());
|
|
67
|
+
for (const c of classes) names.add(baseClassName(String(c)));
|
|
68
|
+
}
|
|
69
|
+
cached = { count, byCompendium };
|
|
70
|
+
LISTED_CLASS_NAMES.set(registry, cached);
|
|
71
|
+
}
|
|
72
|
+
return (_a = cached.byCompendium.get(compendium)) != null ? _a : NO_NAMES;
|
|
73
|
+
}
|
|
74
|
+
function attributeUnclassedSpell(spellClasses, casters, registry) {
|
|
75
|
+
var _a;
|
|
76
|
+
const first = casters[0];
|
|
77
|
+
if (!first) return null;
|
|
78
|
+
const listed = firstListedCasterClass(spellClasses, casters.map((c) => c.classSlug));
|
|
79
|
+
if (listed == null || listed === first.classSlug) return first.classSlug;
|
|
80
|
+
if (first.spellList == null) return first.classSlug;
|
|
81
|
+
const compendium = (_a = registry.getByTypeAndSlug("class", first.classSlug)) == null ? void 0 : _a.compendium;
|
|
82
|
+
if (compendium == null || !listedSpellClassNames(registry, compendium).has(baseClassName(first.classSlug))) return first.classSlug;
|
|
83
|
+
return listed;
|
|
84
|
+
}
|
|
44
85
|
var FULL_CASTER_SLOTS = [
|
|
45
86
|
/* 1 */
|
|
46
87
|
[2, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
@@ -209,6 +250,24 @@ var PACT_MAGIC = [
|
|
|
209
250
|
/* 20 */
|
|
210
251
|
{ level: 5, total: 4 }
|
|
211
252
|
];
|
|
253
|
+
var ARTIFICER_CASTER_SLOTS = HALF_CASTER_SLOTS.map((row) => [...row]);
|
|
254
|
+
ARTIFICER_CASTER_SLOTS[0] = [2, 0, 0, 0, 0];
|
|
255
|
+
function slotTableFor(caster) {
|
|
256
|
+
switch (caster) {
|
|
257
|
+
case "full":
|
|
258
|
+
return FULL_CASTER_SLOTS;
|
|
259
|
+
case "half":
|
|
260
|
+
return HALF_CASTER_SLOTS;
|
|
261
|
+
case "third":
|
|
262
|
+
return THIRD_CASTER_SLOTS;
|
|
263
|
+
case "artificer":
|
|
264
|
+
return ARTIFICER_CASTER_SLOTS;
|
|
265
|
+
default: {
|
|
266
|
+
const _n = caster;
|
|
267
|
+
throw new Error(`unknown caster type ${String(_n)}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
212
271
|
function rowToRecord(row) {
|
|
213
272
|
const out = {};
|
|
214
273
|
row.forEach((n, i) => {
|
|
@@ -217,7 +276,7 @@ function rowToRecord(row) {
|
|
|
217
276
|
return out;
|
|
218
277
|
}
|
|
219
278
|
function deriveSpellSlots(classes) {
|
|
220
|
-
let fullLevels = 0, halfLevels = 0, thirdLevels = 0, warlockLevel = 0;
|
|
279
|
+
let fullLevels = 0, halfLevels = 0, thirdLevels = 0, artificerLevels = 0, warlockLevel = 0;
|
|
221
280
|
const regular = [];
|
|
222
281
|
for (const c of classes) {
|
|
223
282
|
if (c.casterType === "pact") {
|
|
@@ -225,28 +284,55 @@ function deriveSpellSlots(classes) {
|
|
|
225
284
|
continue;
|
|
226
285
|
}
|
|
227
286
|
regular.push({ caster: c.casterType, level: c.level });
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
287
|
+
switch (c.casterType) {
|
|
288
|
+
case "full":
|
|
289
|
+
fullLevels += c.level;
|
|
290
|
+
break;
|
|
291
|
+
case "half":
|
|
292
|
+
halfLevels += c.level;
|
|
293
|
+
break;
|
|
294
|
+
case "third":
|
|
295
|
+
thirdLevels += c.level;
|
|
296
|
+
break;
|
|
297
|
+
case "artificer":
|
|
298
|
+
artificerLevels += c.level;
|
|
299
|
+
break;
|
|
300
|
+
default: {
|
|
301
|
+
const _n = c.casterType;
|
|
302
|
+
throw new Error(`unknown caster type ${String(_n)}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
231
305
|
}
|
|
232
306
|
let standard = {};
|
|
233
307
|
if (regular.length === 1) {
|
|
234
308
|
const only = regular[0];
|
|
309
|
+
const table = slotTableFor(only.caster);
|
|
235
310
|
const idx = only.level - 1;
|
|
236
|
-
if (
|
|
237
|
-
if (idx >= 0 && idx < HALF_CASTER_SLOTS.length) standard = rowToRecord(HALF_CASTER_SLOTS[idx]);
|
|
238
|
-
} else if (only.caster === "third") {
|
|
239
|
-
if (idx >= 0 && idx < THIRD_CASTER_SLOTS.length) standard = rowToRecord(THIRD_CASTER_SLOTS[idx]);
|
|
240
|
-
} else {
|
|
241
|
-
if (only.level >= 1 && only.level <= FULL_CASTER_SLOTS.length) standard = rowToRecord(FULL_CASTER_SLOTS[only.level - 1]);
|
|
242
|
-
}
|
|
311
|
+
if (idx >= 0 && idx < table.length) standard = rowToRecord(table[idx]);
|
|
243
312
|
} else if (regular.length >= 2) {
|
|
244
|
-
const cl = fullLevels + Math.floor(halfLevels / 2) + Math.floor(thirdLevels / 3);
|
|
313
|
+
const cl = fullLevels + Math.floor(halfLevels / 2) + Math.floor(thirdLevels / 3) + Math.ceil(artificerLevels / 2);
|
|
245
314
|
if (cl >= 1 && cl <= FULL_CASTER_SLOTS.length) standard = rowToRecord(FULL_CASTER_SLOTS[cl - 1]);
|
|
246
315
|
}
|
|
247
316
|
const pact = warlockLevel >= 1 && warlockLevel <= PACT_MAGIC.length ? PACT_MAGIC[warlockLevel - 1] : null;
|
|
248
317
|
return { standard, pact };
|
|
249
318
|
}
|
|
319
|
+
var PREPARED_COLUMNS = ["Prepared Spells", "Spells Prepared"];
|
|
320
|
+
function preparedLevelTerm(caster, level) {
|
|
321
|
+
switch (caster) {
|
|
322
|
+
case "full":
|
|
323
|
+
case "pact":
|
|
324
|
+
return level;
|
|
325
|
+
case "half":
|
|
326
|
+
case "artificer":
|
|
327
|
+
return Math.floor(level / 2);
|
|
328
|
+
case "third":
|
|
329
|
+
return Math.floor(level / 3);
|
|
330
|
+
default: {
|
|
331
|
+
const _n = caster;
|
|
332
|
+
throw new Error(`unknown caster type ${String(_n)}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
250
336
|
function computeSpellLimits(inputs) {
|
|
251
337
|
const out = [];
|
|
252
338
|
for (const i of inputs) {
|
|
@@ -255,8 +341,8 @@ function computeSpellLimits(inputs) {
|
|
|
255
341
|
const mod = abilityModifier(i.abilityScore);
|
|
256
342
|
let preparedOrKnown;
|
|
257
343
|
if (p.preparation === "prepared") {
|
|
258
|
-
const
|
|
259
|
-
preparedOrKnown = Math.max(1, mod +
|
|
344
|
+
const fromTable = readTableColumn(p.table, i.level, PREPARED_COLUMNS);
|
|
345
|
+
preparedOrKnown = fromTable !== null ? fromTable : Math.max(1, mod + preparedLevelTerm(p.casterType, i.level));
|
|
260
346
|
} else {
|
|
261
347
|
preparedOrKnown = readTableColumn(p.table, i.level, ["Spells Known", "Prepared Spells"]);
|
|
262
348
|
}
|
|
@@ -269,6 +355,11 @@ export {
|
|
|
269
355
|
resolveSpellcasting,
|
|
270
356
|
effectiveSpellcastingAbility,
|
|
271
357
|
normalizeKnownSpell,
|
|
358
|
+
listedSpellClassNames,
|
|
359
|
+
attributeUnclassedSpell,
|
|
360
|
+
slotTableFor,
|
|
272
361
|
deriveSpellSlots,
|
|
362
|
+
PREPARED_COLUMNS,
|
|
363
|
+
preparedLevelTerm,
|
|
273
364
|
computeSpellLimits
|
|
274
365
|
};
|