@archivist-gg/dnd5e 0.3.10 → 0.3.13

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.
Files changed (174) hide show
  1. package/LICENSES/SRD.md +38 -3
  2. package/dist/armor/armor.codec.js +3 -3
  3. package/dist/armor/armor.parser.js +2 -2
  4. package/dist/armor/armor.schema.d.ts +1 -0
  5. package/dist/armor/armor.schema.js +1 -1
  6. package/dist/armor/armor.types.d.ts +2 -0
  7. package/dist/background/background.codec.js +5 -5
  8. package/dist/background/background.parser.js +4 -4
  9. package/dist/background/background.schema.js +3 -3
  10. package/dist/chunk-2LULMQTF.js +14 -0
  11. package/dist/{chunk-CBEKVAX4.js → chunk-4BZ47YJ4.js} +10 -3
  12. package/dist/{chunk-22MOUU2G.js → chunk-4SLOJXJ4.js} +1 -1
  13. package/dist/{chunk-2DFENQIJ.js → chunk-5GKJAUMX.js} +2 -0
  14. package/dist/{chunk-J77CKYV3.js → chunk-5KGV6TF7.js} +1 -1
  15. package/dist/{chunk-3UNP3G4D.js → chunk-6ZY3U6BQ.js} +1 -1
  16. package/dist/{chunk-DNAJRMNN.js → chunk-A54HHCWW.js} +6 -7
  17. package/dist/{chunk-2M34FLAY.js → chunk-BRGLDWUP.js} +3 -1
  18. package/dist/chunk-CM5CWO4K.js +735 -0
  19. package/dist/{chunk-MI7P3NX3.js → chunk-DPM6V7YX.js} +2 -2
  20. package/dist/chunk-EJP263OP.js +186 -0
  21. package/dist/{chunk-G247QXWW.js → chunk-EL6QPF6I.js} +1 -1
  22. package/dist/{chunk-SMLXZUBH.js → chunk-EYX4JMAU.js} +4 -1
  23. package/dist/{chunk-AW3EHF3L.js → chunk-FC4IGH5Y.js} +1 -1
  24. package/dist/{chunk-PI4LLJG4.js → chunk-FPGXFD2M.js} +2 -2
  25. package/dist/{chunk-23LZLBJK.js → chunk-G6MHJDVT.js} +6 -2
  26. package/dist/{chunk-NWDF5HG3.js → chunk-G7ED5H2G.js} +1 -1
  27. package/dist/chunk-H5PTKYXL.js +101 -0
  28. package/dist/{chunk-LWFTHJIE.js → chunk-HHBD4SQ6.js} +1 -1
  29. package/dist/{chunk-PP2UHLBA.js → chunk-HJQNK3J5.js} +8 -0
  30. package/dist/{chunk-JC5UNIVM.js → chunk-HS6FIOLP.js} +2 -0
  31. package/dist/chunk-IHE6KVC3.js +13 -0
  32. package/dist/{chunk-BLRW2UU6.js → chunk-J53ERF6K.js} +2 -2
  33. package/dist/{chunk-MQ747UCR.js → chunk-JNNNBEUH.js} +65 -2
  34. package/dist/{chunk-LDDCNPHD.js → chunk-K5NJBTE2.js} +1 -1
  35. package/dist/{chunk-4ISR76DH.js → chunk-KSTV7J2U.js} +9 -3
  36. package/dist/chunk-LBEXLN6I.js +91 -0
  37. package/dist/{chunk-UBBKSYBY.js → chunk-LHZXYFBU.js} +30 -1
  38. package/dist/{chunk-OYUEUKKF.js → chunk-LVX6TQ3R.js} +12 -8
  39. package/dist/{chunk-R747YKS7.js → chunk-M2OWVAZG.js} +1 -1
  40. package/dist/{chunk-7YU4NPKR.js → chunk-MC5YJ4PB.js} +1 -1
  41. package/dist/{chunk-JCEV7KYN.js → chunk-MUIU7RZ3.js} +1 -1
  42. package/dist/{chunk-JSZ4H6AQ.js → chunk-MWCCGPG3.js} +1 -1
  43. package/dist/{chunk-R2ZV233X.js → chunk-MYY2C5MB.js} +3 -3
  44. package/dist/{chunk-S56D6B6C.js → chunk-PLOSP4XQ.js} +3 -3
  45. package/dist/{chunk-JANNRGJC.js → chunk-PX25R3DK.js} +1 -1
  46. package/dist/{chunk-V373TRJE.js → chunk-Q5XTEYHD.js} +191 -125
  47. package/dist/{chunk-MAH6DCRI.js → chunk-Q6UOHCCT.js} +1 -1
  48. package/dist/{chunk-HLQAFZKQ.js → chunk-QEO7LYTG.js} +216 -95
  49. package/dist/{chunk-PJMG5XV3.js → chunk-QSBJ6NEM.js} +1 -1
  50. package/dist/{chunk-BL3VELKP.js → chunk-R2V5LN3I.js} +1 -1
  51. package/dist/{chunk-4DOMDEBZ.js → chunk-RQNJXADQ.js} +1 -1
  52. package/dist/{chunk-GFZ7PITJ.js → chunk-S3YUXDSC.js} +6 -1
  53. package/dist/chunk-T5GZBKIQ.js +927 -0
  54. package/dist/{chunk-PZCE7DJM.js → chunk-UE6LKRXQ.js} +15 -1
  55. package/dist/{chunk-5N2GW72F.js → chunk-UZXG6QSY.js} +2 -1
  56. package/dist/{chunk-QHMWA3SZ.js → chunk-VDPRBUU5.js} +1 -1
  57. package/dist/{chunk-4XTNPNQB.js → chunk-VPYBK2MG.js} +1 -1
  58. package/dist/{chunk-V6LJFP4R.js → chunk-X7VZY4ON.js} +2 -2
  59. package/dist/{chunk-HZA7OE7N.js → chunk-XCFC7LGF.js} +2 -1
  60. package/dist/{chunk-BIA32MQ5.js → chunk-XJRNEQPD.js} +1 -1
  61. package/dist/{chunk-OZP6JFGT.js → chunk-XY6X2APM.js} +3 -1
  62. package/dist/{chunk-UIRMA5KM.js → chunk-YDGMBMYI.js} +1 -1
  63. package/dist/{chunk-6X4KUDMU.js → chunk-ZCTUYGNV.js} +7 -2
  64. package/dist/{chunk-VQAXTIBW.js → chunk-ZDAEGJH4.js} +2 -0
  65. package/dist/{chunk-XTRDCSJB.js → chunk-ZMJQUZQH.js} +4 -1
  66. package/dist/chunk-ZUQW5VBZ.js +89 -0
  67. package/dist/class/class.codec.js +7 -7
  68. package/dist/class/class.parser.js +6 -6
  69. package/dist/class/class.schema.d.ts +10 -0
  70. package/dist/class/class.schema.js +5 -5
  71. package/dist/entities/base-item-resolver.js +2 -2
  72. package/dist/entities/slug.d.ts +18 -8
  73. package/dist/entities/slug.js +3 -1
  74. package/dist/feat/feat.codec.js +5 -5
  75. package/dist/feat/feat.parser.js +4 -4
  76. package/dist/feat/feat.schema.d.ts +16 -3
  77. package/dist/feat/feat.schema.js +3 -3
  78. package/dist/index.js +5277 -2017
  79. package/dist/item/item.actions-map.d.ts +40 -5
  80. package/dist/item/item.actions-map.js +5 -84
  81. package/dist/item/item.attunement.js +3 -9
  82. package/dist/item/item.bonuses.js +5 -2
  83. package/dist/item/item.codec.js +3 -3
  84. package/dist/item/item.conditions.js +4 -1
  85. package/dist/item/item.conditions.types.d.ts +4 -0
  86. package/dist/item/item.cost.d.ts +3 -0
  87. package/dist/item/item.cost.js +29 -0
  88. package/dist/item/item.icon.d.ts +15 -0
  89. package/dist/item/item.icon.js +211 -0
  90. package/dist/item/item.parser.js +2 -2
  91. package/dist/item/item.schema.d.ts +16 -1
  92. package/dist/item/item.schema.js +3 -1
  93. package/dist/item/item.types.d.ts +9 -2
  94. package/dist/monster/monster.parser.js +5 -5
  95. package/dist/monster/monster.schema.js +4 -4
  96. package/dist/optional-feature/optional-feature.codec.js +4 -4
  97. package/dist/optional-feature/optional-feature.parser.js +3 -3
  98. package/dist/optional-feature/optional-feature.schema.d.ts +229 -3
  99. package/dist/optional-feature/optional-feature.schema.js +6 -2
  100. package/dist/pc/pc.additional-spells.js +4 -4
  101. package/dist/pc/pc.asi-flatten.d.ts +62 -1
  102. package/dist/pc/pc.asi-flatten.js +16 -0
  103. package/dist/pc/pc.conditions.js +1 -1
  104. package/dist/pc/pc.containment.d.ts +45 -0
  105. package/dist/pc/pc.containment.js +24 -0
  106. package/dist/pc/pc.decision-engine.d.ts +21 -3
  107. package/dist/pc/pc.decision-engine.js +23 -14
  108. package/dist/pc/pc.entry-overrides.d.ts +79 -0
  109. package/dist/pc/pc.entry-overrides.js +40 -0
  110. package/dist/pc/pc.equipment.d.ts +2 -2
  111. package/dist/pc/pc.equipment.js +18 -7
  112. package/dist/pc/pc.feature-effects.js +2 -2
  113. package/dist/pc/pc.infusions.d.ts +220 -0
  114. package/dist/pc/pc.infusions.js +64 -0
  115. package/dist/pc/pc.parser.js +18 -1
  116. package/dist/pc/pc.pools.d.ts +1 -1
  117. package/dist/pc/pc.pools.js +11 -3
  118. package/dist/pc/pc.proficiencies.js +21 -14
  119. package/dist/pc/pc.recalc.d.ts +39 -36
  120. package/dist/pc/pc.recalc.js +60 -32
  121. package/dist/pc/pc.resolver.js +21 -14
  122. package/dist/pc/pc.resource-seed.js +1 -1
  123. package/dist/pc/pc.resources.d.ts +6 -1
  124. package/dist/pc/pc.resources.js +3 -1
  125. package/dist/pc/pc.rest.d.ts +21 -1
  126. package/dist/pc/pc.rest.js +52 -19
  127. package/dist/pc/pc.schema.d.ts +14 -0
  128. package/dist/pc/pc.schema.js +1 -1
  129. package/dist/pc/pc.slotting.d.ts +36 -3
  130. package/dist/pc/pc.slotting.js +13 -5
  131. package/dist/pc/pc.tool-picks.d.ts +51 -0
  132. package/dist/pc/pc.tool-picks.js +18 -0
  133. package/dist/pc/pc.types.d.ts +70 -12
  134. package/dist/pc/pool-layout.d.ts +14 -0
  135. package/dist/pc/pool-layout.js +7 -3
  136. package/dist/race/race.codec.js +6 -6
  137. package/dist/race/race.parser.js +5 -5
  138. package/dist/race/race.schema.js +4 -4
  139. package/dist/schemas/attack-schema.d.ts +1 -1
  140. package/dist/schemas/choice-schema.js +2 -2
  141. package/dist/schemas/feature-effect-schema.d.ts +16 -3
  142. package/dist/schemas/feature-effect-schema.js +1 -1
  143. package/dist/schemas/feature-schema.js +3 -3
  144. package/dist/schemas/selection-pool-schema.d.ts +10 -0
  145. package/dist/schemas/selection-pool-schema.js +1 -1
  146. package/dist/spell/spell.codec.js +3 -3
  147. package/dist/spell/spell.parser.js +2 -2
  148. package/dist/spell/spell.scaling.d.ts +34 -10
  149. package/dist/spell/spell.scaling.js +36 -4
  150. package/dist/spell/spell.schema.d.ts +1 -0
  151. package/dist/spell/spell.schema.js +1 -1
  152. package/dist/spell/spell.types.d.ts +4 -0
  153. package/dist/srd/retired-items.d.ts +14 -0
  154. package/dist/srd/retired-items.js +11 -0
  155. package/dist/subclass/subclass.codec.js +7 -7
  156. package/dist/subclass/subclass.parser.js +6 -6
  157. package/dist/subclass/subclass.schema.d.ts +10 -0
  158. package/dist/subclass/subclass.schema.js +5 -5
  159. package/dist/types/choice.d.ts +8 -0
  160. package/dist/types/equipment-grant.d.ts +18 -1
  161. package/dist/types/equipment-grant.js +12 -0
  162. package/dist/types/feature-effect.d.ts +6 -1
  163. package/dist/types/optional-feature.types.d.ts +79 -1
  164. package/dist/types/selection-pool.d.ts +16 -1
  165. package/dist/weapon/weapon.classify.d.ts +10 -8
  166. package/dist/weapon/weapon.classify.js +2 -2
  167. package/dist/weapon/weapon.codec.js +3 -3
  168. package/dist/weapon/weapon.parser.js +2 -2
  169. package/dist/weapon/weapon.schema.d.ts +1 -0
  170. package/dist/weapon/weapon.schema.js +1 -1
  171. package/dist/weapon/weapon.types.d.ts +2 -0
  172. package/package.json +1 -1
  173. package/dist/chunk-O4SRD3J5.js +0 -165
  174. package/dist/chunk-WXWPK3LI.js +0 -55
@@ -3,10 +3,19 @@ function spellScales(spell) {
3
3
  var _a, _b, _c, _d;
4
4
  return ((_b = (_a = spell.casting_options) == null ? void 0 : _a.length) != null ? _b : 0) > 0 || ((_d = (_c = spell.at_higher_levels) == null ? void 0 : _c.length) != null ? _d : 0) > 0;
5
5
  }
6
+ function spellBaseRoll(spell) {
7
+ const roll = typeof spell.damage_roll === "string" ? spell.damage_roll.trim() : "";
8
+ return roll !== "" ? roll : null;
9
+ }
6
10
  function spellEffectPartsAtSlot(spell, slotLevel) {
7
- var _a;
8
- const opt = ((_a = spell.casting_options) != null ? _a : []).find((o) => o.type === `slot_level_${slotLevel}`);
9
- if (!opt) return null;
11
+ var _a, _b;
12
+ const base = (_a = spell.level) != null ? _a : 0;
13
+ if (base === 0) return null;
14
+ const opt = ((_b = spell.casting_options) != null ? _b : []).find((o) => o.type === `slot_level_${slotLevel}`);
15
+ if (!opt) {
16
+ const roll = spellBaseRoll(spell);
17
+ return roll !== null && slotLevel === base ? { field: "damage_roll", value: roll } : null;
18
+ }
10
19
  if (opt.damage_roll) return { field: "damage_roll", value: opt.damage_roll };
11
20
  if (typeof opt.target_count === "number") {
12
21
  if (opt.target_count === slotLevel) return null;
@@ -15,6 +24,27 @@ function spellEffectPartsAtSlot(spell, slotLevel) {
15
24
  if (opt.duration) return { field: "duration", value: opt.duration };
16
25
  return opt.desc != null ? { field: "desc", value: opt.desc } : null;
17
26
  }
27
+ var NON_ROLL_SCALES = /* @__PURE__ */ new Set(["duration", "target_count"]);
28
+ var NON_ROLL_OPTION_FIELDS = /* @__PURE__ */ new Set([...NON_ROLL_SCALES, "concentration"]);
29
+ function spellBaseRollAtSlot(spell, slotLevel) {
30
+ var _a, _b, _c;
31
+ const base = (_a = spell.level) != null ? _a : 0;
32
+ if (base === 0 || slotLevel < base) return null;
33
+ const roll = spellBaseRoll(spell);
34
+ if (roll === null) return null;
35
+ const slotOptions = ((_b = spell.casting_options) != null ? _b : []).filter((o) => {
36
+ var _a2;
37
+ return /^slot_level_\d+$/.test(String((_a2 = o.type) != null ? _a2 : ""));
38
+ });
39
+ if (slotOptions.length > 0) {
40
+ const onlyNonRoll = slotOptions.every((o) => {
41
+ const fields = Object.entries(o).filter(([k, v]) => k !== "type" && v != null).map(([k]) => k);
42
+ return fields.some((k) => NON_ROLL_SCALES.has(k)) && fields.every((k) => NON_ROLL_OPTION_FIELDS.has(k));
43
+ });
44
+ return onlyNonRoll ? roll : null;
45
+ }
46
+ return ((_c = spell.at_higher_levels) != null ? _c : []).some((t) => typeof t === "string" && t.trim() !== "") ? null : roll;
47
+ }
18
48
  function spellEffectAtSlot(spell, slotLevel) {
19
49
  var _a, _b;
20
50
  return (_b = (_a = spellEffectPartsAtSlot(spell, slotLevel)) == null ? void 0 : _a.value) != null ? _b : null;
@@ -30,7 +60,7 @@ function spellEffectAtCharacterLevel(spell, characterLevel) {
30
60
  const n = Number(m[1]);
31
61
  if (n <= characterLevel && (best === null || n > best.n)) best = { n, roll: opt.damage_roll };
32
62
  }
33
- return best ? best.roll : null;
63
+ return best ? best.roll : spellBaseRoll(spell);
34
64
  }
35
65
  function upcastLevelsFor(spell, ownedSlotLevels) {
36
66
  var _a;
@@ -39,6 +69,8 @@ function upcastLevelsFor(spell, ownedSlotLevels) {
39
69
  return ownedSlotLevels.filter((l) => l > base).sort((a, b) => a - b);
40
70
  }
41
71
  export {
72
+ spellBaseRoll,
73
+ spellBaseRollAtSlot,
42
74
  spellEffectAtCharacterLevel,
43
75
  spellEffectAtSlot,
44
76
  spellEffectPartsAtSlot,
@@ -40,6 +40,7 @@ export declare const spellEntitySchema: z.ZodObject<{
40
40
  damage: z.ZodOptional<z.ZodObject<{
41
41
  types: z.ZodArray<z.ZodString>;
42
42
  }, z.core.$strip>>;
43
+ damage_roll: z.ZodOptional<z.ZodString>;
43
44
  saving_throw: z.ZodOptional<z.ZodObject<{
44
45
  ability: z.ZodString;
45
46
  }, z.core.$strip>>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spellEntitySchema
3
- } from "../chunk-VQAXTIBW.js";
3
+ } from "../chunk-ZDAEGJH4.js";
4
4
  import "../chunk-UA5KS2PL.js";
5
5
  export {
6
6
  spellEntitySchema
@@ -16,6 +16,10 @@ export interface Spell {
16
16
  damage?: {
17
17
  types: string[];
18
18
  };
19
+ /** The BASE roll: the roll at the spell's own level, or a cantrip's tier-1 roll (before its first
20
+ * `player_level_<N>` option). Like `casting_options[].damage_roll` it also carries healing rolls
21
+ * (Cure Wounds `2d8`). Mirrors Open5e v2's top-level `damage_roll`. */
22
+ damage_roll?: string;
19
23
  saving_throw?: {
20
24
  ability: string;
21
25
  };
@@ -0,0 +1,14 @@
1
+ export interface RetiredItem {
2
+ retired_slug: string;
3
+ retired_name: string;
4
+ /** The bundle-relative note path the retired record shipped at (dnd5e 0.3.12). */
5
+ retired_path: string;
6
+ kept_slug: string;
7
+ kept_name: string;
8
+ }
9
+ export declare const RETIRED_ITEMS: readonly RetiredItem[];
10
+ /** The kept slug for a retired item slug, or undefined. */
11
+ export declare function keptSlugFor(slug: string): string | undefined;
12
+ /** The kept slug for an UNWRAPPED link target: a slug, or a compendium path (`SRD 5e/Magic Items/Hand Crossbow +2`), read
13
+ * the way `resolveBaseItem` reads one. A vault-root path (`Compendium/SRD 5e/...`) never resolved and is left alone. */
14
+ export declare function keptSlugForLink(target: string): string | undefined;
@@ -0,0 +1,11 @@
1
+ import {
2
+ RETIRED_ITEMS,
3
+ keptSlugFor,
4
+ keptSlugForLink
5
+ } from "../chunk-CM5CWO4K.js";
6
+ import "../chunk-ZCTUYGNV.js";
7
+ export {
8
+ RETIRED_ITEMS,
9
+ keptSlugFor,
10
+ keptSlugForLink
11
+ };
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  subclassCodec
3
- } from "../chunk-R747YKS7.js";
4
- import "../chunk-J77CKYV3.js";
5
- import "../chunk-BLRW2UU6.js";
3
+ } from "../chunk-M2OWVAZG.js";
4
+ import "../chunk-5KGV6TF7.js";
5
+ import "../chunk-J53ERF6K.js";
6
6
  import "../chunk-4U55VNC7.js";
7
- import "../chunk-23LZLBJK.js";
7
+ import "../chunk-G6MHJDVT.js";
8
8
  import "../chunk-CJYCVNW2.js";
9
- import "../chunk-PI4LLJG4.js";
9
+ import "../chunk-FPGXFD2M.js";
10
10
  import "../chunk-WYGD2UGN.js";
11
11
  import "../chunk-ZJXSXVFP.js";
12
- import "../chunk-2M34FLAY.js";
13
- import "../chunk-XTRDCSJB.js";
12
+ import "../chunk-BRGLDWUP.js";
13
+ import "../chunk-ZMJQUZQH.js";
14
14
  import "../chunk-UA5KS2PL.js";
15
15
  export {
16
16
  subclassCodec
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  parseSubclass
3
- } from "../chunk-J77CKYV3.js";
4
- import "../chunk-BLRW2UU6.js";
3
+ } from "../chunk-5KGV6TF7.js";
4
+ import "../chunk-J53ERF6K.js";
5
5
  import "../chunk-4U55VNC7.js";
6
- import "../chunk-23LZLBJK.js";
6
+ import "../chunk-G6MHJDVT.js";
7
7
  import "../chunk-CJYCVNW2.js";
8
- import "../chunk-PI4LLJG4.js";
8
+ import "../chunk-FPGXFD2M.js";
9
9
  import "../chunk-WYGD2UGN.js";
10
10
  import "../chunk-ZJXSXVFP.js";
11
- import "../chunk-2M34FLAY.js";
12
- import "../chunk-XTRDCSJB.js";
11
+ import "../chunk-BRGLDWUP.js";
12
+ import "../chunk-ZMJQUZQH.js";
13
13
  import "../chunk-UA5KS2PL.js";
14
14
  export {
15
15
  parseSubclass
@@ -106,8 +106,18 @@ export declare const subclassEntitySchema: z.ZodObject<{
106
106
  }, z.core.$strip>;
107
107
  count: z.ZodObject<{
108
108
  column: z.ZodString;
109
+ label: z.ZodOptional<z.ZodString>;
109
110
  }, z.core.$strip>;
110
111
  replaceable: z.ZodOptional<z.ZodBoolean>;
112
+ active: z.ZodOptional<z.ZodObject<{
113
+ column: z.ZodString;
114
+ label: z.ZodString;
115
+ verb: z.ZodString;
116
+ counter_label: z.ZodOptional<z.ZodString>;
117
+ create_label: z.ZodOptional<z.ZodString>;
118
+ create_verb: z.ZodOptional<z.ZodString>;
119
+ }, z.core.$strip>>;
120
+ head_resource: z.ZodOptional<z.ZodString>;
111
121
  }, z.core.$strip>>>;
112
122
  pool_grants: z.ZodOptional<z.ZodArray<z.ZodObject<{
113
123
  pool: z.ZodString;
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  subclassEntitySchema
3
- } from "../chunk-BLRW2UU6.js";
4
- import "../chunk-23LZLBJK.js";
3
+ } from "../chunk-J53ERF6K.js";
4
+ import "../chunk-G6MHJDVT.js";
5
5
  import "../chunk-CJYCVNW2.js";
6
- import "../chunk-PI4LLJG4.js";
6
+ import "../chunk-FPGXFD2M.js";
7
7
  import "../chunk-WYGD2UGN.js";
8
8
  import "../chunk-ZJXSXVFP.js";
9
- import "../chunk-2M34FLAY.js";
10
- import "../chunk-XTRDCSJB.js";
9
+ import "../chunk-BRGLDWUP.js";
10
+ import "../chunk-ZMJQUZQH.js";
11
11
  import "../chunk-UA5KS2PL.js";
12
12
  export {
13
13
  subclassEntitySchema
@@ -75,6 +75,14 @@ export interface EntityFilter {
75
75
  /** Armor proficiency class. Matched against an armor entity's `category`
76
76
  * field exactly; "shield" selects shields. */
77
77
  armor_category?: "light" | "medium" | "heavy" | "shield";
78
+ /** Item axis: an item entity's `type` ("instrument", "artisan's tools", "gaming set"); ANY listed type matches.
79
+ * Compared case-insensitively with apostrophes, separators and a plural "s" folded (`categoryWords` in
80
+ * pc.tool-picks.ts), so "artisans tools" matches "artisan's tools". A starting-equipment tool category
81
+ * (`musical-instrument`, `artisan's-tools`, `gaming-set`, or an `X-or-Y` union of them) sets it. */
82
+ item_type?: string[];
83
+ /** Item axis: true keeps only MUNDANE items, dropping one whose `rarity` names a magic tier. Starting gear sets
84
+ * it, because magic instruments (Instrument of Scribing, +3 Rhythm-Maker's Drum) also carry `type: instrument`. */
85
+ mundane?: boolean;
78
86
  /** Spell axis: filter spells by class list, level, and edition. Set together on a
79
87
  * select-entity{entity_type:"spell"} choice (e.g. Magic Initiate). */
80
88
  list?: string;
@@ -1,7 +1,9 @@
1
1
  /** One thing a starting-equipment option grants. `item` is a BARE compendium
2
2
  * slug (e.g. "chain-mail"); the seeder resolves it to the full edition slug.
3
3
  * `category` is a player-picked class of item ("martial-weapon",
4
- * "simple-weapon", "martial-melee-weapon", "any-armor", "shield", …) resolved
4
+ * "simple-weapon", "martial-melee-weapon", "any-armor", "shield",
5
+ * "musical-instrument", "artisan's-tools", "gaming-set", a tool `X-or-Y` union;
6
+ * the vocabulary is `categoryToEntitySelect`'s in pc.decision-engine.ts) resolved
5
7
  * by a nested select-entity. `gold` is gp folded into the bundle. */
6
8
  export type EquipmentGrant =
7
9
  /** `contains_value` (COPPER; `1500` = 15 gp) is seeded as gold by the plugin's starting-equipment seeder
@@ -19,6 +21,21 @@ export type EquipmentGrant =
19
21
  } | {
20
22
  gold: number;
21
23
  };
24
+ /** THE rule for which grant is a player-picked CATEGORY: an object whose `category` is a non-empty string. Shared by
25
+ * the engine's nested-pick synthesis and the plugin's seeder, so the nth category grant of an option always
26
+ * consumes the nth pick key and the two can never count a malformed grant differently. */
27
+ export declare function isCategoryGrant(g: unknown): g is Extract<EquipmentGrant, {
28
+ category: string;
29
+ }>;
30
+ /** The persistence key of the nested pick for grant `k` of option `j` of starting-equipment entry `i`: the one
31
+ * spelling the engine emits and the plugin reads. `k` indexes the option's WHOLE grant list, not its category
32
+ * grants alone. */
33
+ export declare const equipmentCategoryKey: (i: number, j: number, k: number) => string;
34
+ /** The ORDERED pick keys of one option's category grants, the order `resolveGrants` consumes them in. */
35
+ export declare const equipmentCategoryKeys: (grants: readonly unknown[], i: number, j: number) => string[];
36
+ /** True for a starting-equipment decision key (`equipment-<i>` and its nested picks). The Equipment step owns
37
+ * these; every other step's decision strip leaves them out. */
38
+ export declare const isStartingEquipmentKey: (key: string) => boolean;
22
39
  /** One selectable option of a `kind:"choice"` starting-equipment entry. `label`
23
40
  * is the human display string (the `.pc-cb-eqopt` text); `grants` is what seeds. */
24
41
  export interface EquipmentOption {
@@ -0,0 +1,12 @@
1
+ import {
2
+ equipmentCategoryKey,
3
+ equipmentCategoryKeys,
4
+ isCategoryGrant,
5
+ isStartingEquipmentKey
6
+ } from "../chunk-2LULMQTF.js";
7
+ export {
8
+ equipmentCategoryKey,
9
+ equipmentCategoryKeys,
10
+ isCategoryGrant,
11
+ isStartingEquipmentKey
12
+ };
@@ -1,5 +1,10 @@
1
1
  import type { Ability } from "./choice.js";
2
2
  export type SenseType = "darkvision" | "blindsight" | "tremorsense" | "truesight";
3
+ /** A damage rider's weapon scope, the `damage-bonus` arm's structured `applies_to` words (ART-c1 Task 9b, controller
4
+ * ruling 8): `melee` and `ranged` are the weapon's CATEGORY (a thrown melee weapon stays melee), `unarmed` the engine's
5
+ * Unarmed Strike row, `finesse` and `thrown` the row's properties, and `weapon` every attack row (today's reach, the
6
+ * Unarmed Strike row included). A list reaches a row when ANY word matches it. */
7
+ export type WeaponScope = "weapon" | "melee" | "ranged" | "unarmed" | "finesse" | "thrown";
3
8
  /** Present on every arm: whose numbers the effect changes. Absent === "self". The engine's fold readers skip
4
9
  * every effect whose subject is present and not "self" (`foldsOnSelf` in pc.feature-effects.ts). */
5
10
  type Subject = {
@@ -69,7 +74,7 @@ export type FeatureEffect = ({
69
74
  kind: "damage-bonus";
70
75
  damage_type: string;
71
76
  amount: string;
72
- applies_to?: "weapon" | "spell" | "all";
77
+ applies_to?: "spell" | "all" | WeaponScope | WeaponScope[];
73
78
  } & Qualified) | ({
74
79
  kind: "proficiency";
75
80
  proficiency_type: "skill" | "tool" | "language" | "saving-throw" | "armor" | "weapon";
@@ -8,7 +8,7 @@ import type { AdditionalSpellsEntry, ProgressionEntry } from "../schemas/entity-
8
8
  * `feature_type` field is now an open string (see {@link OptionalFeatureEntity})
9
9
  * so homebrew categories parse; this union is kept purely as a reference list.
10
10
  */
11
- export type OptionalFeatureKind = "invocation" | "fighting_style" | "metamagic" | "maneuver" | "infusion";
11
+ export type OptionalFeatureKind = "invocation" | "fighting_style" | "metamagic" | "maneuver" | "infusion" | "artificer_plan";
12
12
  /** A class/subclass named reference carried by a level prerequisite; mirrors namedRefSchema. */
13
13
  export type OptionalFeatureNamedRef = {
14
14
  name: string;
@@ -45,6 +45,76 @@ export type OptionalFeaturePrerequisite = {
45
45
  entry?: string;
46
46
  entry_summary?: string;
47
47
  };
48
+ /** ART-a (spec §4.2). */
49
+ export interface FilterSpec {
50
+ rarity: string[];
51
+ types?: string[];
52
+ exclude_types?: string[];
53
+ cursed?: false;
54
+ }
55
+ export interface OptionCreates {
56
+ item?: string;
57
+ variant?: {
58
+ candidates: string[];
59
+ };
60
+ filter?: FilterSpec;
61
+ }
62
+ export interface OptionRow {
63
+ key: string;
64
+ name: string;
65
+ min_level: number;
66
+ attunement?: boolean;
67
+ creates: OptionCreates;
68
+ }
69
+ export interface InfuseItem {
70
+ bonuses?: {
71
+ ac?: number;
72
+ weapon_attack?: number;
73
+ weapon_damage?: number;
74
+ spell_attack?: number;
75
+ saving_throws?: number;
76
+ speed?: {
77
+ walk?: number;
78
+ fly?: number;
79
+ swim?: number;
80
+ climb?: number;
81
+ };
82
+ };
83
+ resist?: string[];
84
+ charges?: {
85
+ max: number;
86
+ dice?: string;
87
+ recharge?: string;
88
+ recharge_amount?: string;
89
+ };
90
+ action?: ActionCost;
91
+ /** ART-c1 (R-3 a): the Actions row's range ("Self"); absent draws no range. */
92
+ range?: string;
93
+ }
94
+ export interface InfuseTarget {
95
+ kind: "armor" | "shield" | "weapon" | "gear";
96
+ category?: string[];
97
+ property?: string;
98
+ name_any?: string[];
99
+ }
100
+ export interface InfuseBlock {
101
+ targets: InfuseTarget[];
102
+ targets_label?: string;
103
+ new_object?: string;
104
+ rarity?: string;
105
+ attunement?: {
106
+ required: true;
107
+ };
108
+ choice?: {
109
+ kind: "damage-type";
110
+ options?: string[];
111
+ };
112
+ item?: InfuseItem;
113
+ scales_at?: Array<{
114
+ level: number;
115
+ item: InfuseItem;
116
+ }>;
117
+ }
48
118
  export interface OptionalFeatureEntity {
49
119
  slug: string;
50
120
  name: string;
@@ -87,4 +157,12 @@ export interface OptionalFeatureEntity {
87
157
  optionalfeature_progression?: ProgressionEntry[];
88
158
  /** One wikilink, or an array of them for the multi-fluff-image emit. */
89
159
  image?: string | string[];
160
+ /** ART-a (spec §4.1): a pick is a COPY `<note slug>#<param>`; needs `options` and `item_choice`. */
161
+ repeatable?: true;
162
+ /** `learn`: the param is the item's FULL slug (TCE); `create`: the param is a row key, the item chosen at Create (EFA). */
163
+ item_choice?: "learn" | "create";
164
+ /** The table a copy's param must satisfy (spec §4.2). */
165
+ options?: OptionRow[];
166
+ /** This member infuses an existing object; its effect is an item-vocabulary overlay (spec §4.2). */
167
+ infuse?: InfuseBlock;
90
168
  }
@@ -1,3 +1,12 @@
1
+ /** ART-a (spec §4.5): the at-once counter of an item-bound pool; its defaults are applied at read (`poolActiveWords`). */
2
+ export interface PoolActive {
3
+ column: string;
4
+ label: string;
5
+ verb: string;
6
+ counter_label?: string;
7
+ create_label?: string;
8
+ create_verb?: string;
9
+ }
1
10
  /** A (sub)class-declared selectable pool (e.g. Interdict Boons). The engine is
2
11
  * generic: every game-specific string lives here in data, never in code. */
3
12
  export interface SelectionPool {
@@ -10,11 +19,17 @@ export interface SelectionPool {
10
19
  available_to: "self";
11
20
  };
12
21
  };
13
- /** Pick count read from the owning class table column at the current level. */
22
+ /** Pick count read from the owning class table column at the current level. `label` is the known-counter word,
23
+ * read through `poolCountLabel` (absent reads "Known", ART-a spec §4.5). */
14
24
  count: {
15
25
  column: string;
26
+ label?: string;
16
27
  };
17
28
  replaceable?: boolean;
29
+ /** ART-a (spec §4.5): the at-once counter (Infused Items, Magic Items). */
30
+ active?: PoolActive;
31
+ /** ART-a (spec §4.5): a resource id the tab head shows when the pool spends none of its own. */
32
+ head_resource?: string;
18
33
  }
19
34
  /** Subclass auto-grants that extend a named pool and do NOT count toward picks. */
20
35
  export interface PoolGrant {
@@ -1,13 +1,15 @@
1
1
  import type { WeaponEntity } from "./weapon.types.js";
2
2
  /** The two attack modes a weapon supports, derived from data the SRD pipeline
3
- * actually preserves. The SRD runtime data miscategorizes throwable MELEE
4
- * weapons (dagger/spear/handaxe/javelin/light hammer/trident) as `*-ranged`,
5
- * so the melee/ranged split is reconstructed here instead of trusted:
6
- * a category-ranged weapon is PURE ranged only when it needs ammunition or
7
- * loading, or is one of the two genuinely-ranged thrown weapons (dart, net —
8
- * a closed SRD set; a homebrew weapon whose bare slug is exactly "dart"/"net"
9
- * is force-classified pure ranged). Everything else category-ranged is a
10
- * throwable melee weapon. `reach` is 5 ft, +5 with the reach property. */
3
+ * actually preserves. Since dnd5e 0.3.13 the SRD data files the throwable
4
+ * MELEE weapons (dagger/spear/handaxe/javelin/light hammer/trident) as
5
+ * `*-melee`, but older SRD data, imported records and homebrew can still file
6
+ * them as `*-ranged` (by their thrown range), so the melee/ranged split is
7
+ * reconstructed here instead of trusted: a category-ranged weapon is PURE
8
+ * ranged only when it needs ammunition or loading, or is one of the two
9
+ * genuinely-ranged thrown weapons (dart, net: a closed SRD set; a homebrew
10
+ * weapon whose bare slug is exactly "dart"/"net" is force-classified pure
11
+ * ranged). Everything else category-ranged is a throwable melee weapon.
12
+ * `reach` is 5 ft., +5 with the reach property. */
11
13
  export interface WeaponRangeModes {
12
14
  melee: {
13
15
  reach: number;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  classifyWeaponRange
3
- } from "../chunk-UIRMA5KM.js";
4
- import "../chunk-6X4KUDMU.js";
3
+ } from "../chunk-YDGMBMYI.js";
4
+ import "../chunk-ZCTUYGNV.js";
5
5
  export {
6
6
  classifyWeaponRange
7
7
  };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  weaponCodec
3
- } from "../chunk-LDDCNPHD.js";
4
- import "../chunk-HZA7OE7N.js";
5
- import "../chunk-2DFENQIJ.js";
3
+ } from "../chunk-K5NJBTE2.js";
4
+ import "../chunk-XCFC7LGF.js";
5
+ import "../chunk-5GKJAUMX.js";
6
6
  import "../chunk-UA5KS2PL.js";
7
7
  export {
8
8
  weaponCodec
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseWeapon
3
- } from "../chunk-HZA7OE7N.js";
4
- import "../chunk-2DFENQIJ.js";
3
+ } from "../chunk-XCFC7LGF.js";
4
+ import "../chunk-5GKJAUMX.js";
5
5
  import "../chunk-UA5KS2PL.js";
6
6
  export {
7
7
  parseWeapon
@@ -31,6 +31,7 @@ export declare const weaponEntitySchema: z.ZodObject<{
31
31
  }>;
32
32
  entries: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
33
33
  rendering_hint: z.ZodOptional<z.ZodString>;
34
+ icon: z.ZodOptional<z.ZodString>;
34
35
  has_fluff: z.ZodOptional<z.ZodBoolean>;
35
36
  has_fluff_images: z.ZodOptional<z.ZodBoolean>;
36
37
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  weaponEntitySchema
3
- } from "../chunk-2DFENQIJ.js";
3
+ } from "../chunk-5GKJAUMX.js";
4
4
  import "../chunk-UA5KS2PL.js";
5
5
  export {
6
6
  weaponEntitySchema
@@ -36,6 +36,8 @@ export interface WeaponEntity {
36
36
  entries?: unknown[];
37
37
  /** Carried as the empty string on every converter weapon carrier today (98). */
38
38
  rendering_hint?: string;
39
+ /** The icon key (I3): a key of the renderer's icon set or a Lucide name. */
40
+ icon?: string;
39
41
  has_fluff?: boolean;
40
42
  has_fluff_images?: boolean;
41
43
  /** One wikilink, or an array for >= 2 fluff images (images-ON emit). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archivist-gg/dnd5e",
3
- "version": "0.3.10",
3
+ "version": "0.3.13",
4
4
  "license": "MIT AND CC-BY-4.0",
5
5
  "type": "module",
6
6
  "publishConfig": {