@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.
Files changed (259) hide show
  1. package/LICENSES/SRD.md +25 -6
  2. package/dist/armor/armor.codec.js +4 -3
  3. package/dist/armor/armor.parser.js +3 -2
  4. package/dist/armor/armor.schema.d.ts +4 -0
  5. package/dist/armor/armor.schema.js +2 -1
  6. package/dist/armor/armor.types.d.ts +8 -0
  7. package/dist/background/background.codec.js +7 -6
  8. package/dist/background/background.parser.js +6 -5
  9. package/dist/background/background.schema.d.ts +26 -0
  10. package/dist/background/background.schema.js +5 -4
  11. package/dist/background/background.types.d.ts +22 -0
  12. package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
  13. package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
  14. package/dist/chunk-2FRUSVZS.js +489 -0
  15. package/dist/chunk-2VDTW7QO.js +1580 -0
  16. package/dist/{chunk-ZZGEVJKX.js → chunk-3JOTQW7A.js} +1 -1
  17. package/dist/{chunk-5ZBE4CWV.js → chunk-3PZHBLFG.js} +1 -1
  18. package/dist/chunk-4U55VNC7.js +22 -0
  19. package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
  20. package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
  21. package/dist/{chunk-42Y5IJKT.js → chunk-5RKLL2AD.js} +5 -1
  22. package/dist/{chunk-SE7AZDR3.js → chunk-63XQXPZL.js} +29 -3
  23. package/dist/{chunk-4F6AIZ36.js → chunk-6BFWZW6T.js} +1 -1
  24. package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
  25. package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
  26. package/dist/chunk-6X2NV665.js +33 -0
  27. package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
  28. package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
  29. package/dist/{chunk-TLYDBT5F.js → chunk-CGRLQ34U.js} +64 -7
  30. package/dist/chunk-CJYCVNW2.js +7 -0
  31. package/dist/{chunk-XLSVNUTK.js → chunk-CV5XDJKU.js} +1 -1
  32. package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
  33. package/dist/{chunk-6IRYTM5V.js → chunk-DPUJDOKV.js} +119 -28
  34. package/dist/{chunk-GE4TLPWM.js → chunk-EHDATXP7.js} +1 -1
  35. package/dist/chunk-EVMUJYUD.js +195 -0
  36. package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
  37. package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
  38. package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
  39. package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
  40. package/dist/chunk-IUAAXXNO.js +58 -0
  41. package/dist/{chunk-NXSWH3AE.js → chunk-IWRVOCT5.js} +1 -1
  42. package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
  43. package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
  44. package/dist/{chunk-XTIQWSFM.js → chunk-KADJZGZY.js} +1 -1
  45. package/dist/{chunk-L7E2UT5A.js → chunk-KK33PIDN.js} +5 -1
  46. package/dist/chunk-KPEJMNRD.js +302 -0
  47. package/dist/chunk-KU3YLF6D.js +106 -0
  48. package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
  49. package/dist/chunk-LVQLWRCU.js +15 -0
  50. package/dist/chunk-MI7P3NX3.js +161 -0
  51. package/dist/{chunk-PHQRGDRQ.js → chunk-N3A5ICBO.js} +5 -1
  52. package/dist/chunk-O4SRD3J5.js +165 -0
  53. package/dist/chunk-OAXWSVJB.js +81 -0
  54. package/dist/chunk-OZP6JFGT.js +162 -0
  55. package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
  56. package/dist/chunk-PP2UHLBA.js +50 -0
  57. package/dist/chunk-PVCEA4HZ.js +6 -0
  58. package/dist/{chunk-RSDRMH54.js → chunk-RF4TYCA2.js} +1 -1
  59. package/dist/chunk-RLGQ5PZZ.js +16 -0
  60. package/dist/chunk-RVXC6ZHY.js +89 -0
  61. package/dist/chunk-S7REMWW4.js +21 -0
  62. package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
  63. package/dist/chunk-TOM66P2P.js +38 -0
  64. package/dist/chunk-UA5KS2PL.js +26 -0
  65. package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
  66. package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
  67. package/dist/{chunk-BIK4DFWK.js → chunk-ULCQ73LA.js} +1 -1
  68. package/dist/{chunk-2BWAID3Y.js → chunk-UMWIPLLM.js} +29 -3
  69. package/dist/chunk-UQ3ZFCWD.js +178 -0
  70. package/dist/chunk-UXPGW4TI.js +101 -0
  71. package/dist/chunk-V2MJE6NC.js +133 -0
  72. package/dist/{chunk-D3CLOBE3.js → chunk-V373TRJE.js} +48 -10
  73. package/dist/chunk-VQAXTIBW.js +100 -0
  74. package/dist/chunk-W74BCA7V.js +159 -0
  75. package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
  76. package/dist/{chunk-MDEJHMKK.js → chunk-WHVLNFTG.js} +26 -5
  77. package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
  78. package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
  79. package/dist/chunk-X3D6LXUU.js +185 -0
  80. package/dist/chunk-XJ2F2WO6.js +8 -0
  81. package/dist/{chunk-73HOFQQ5.js → chunk-Y4AGLCY6.js} +1 -1
  82. package/dist/chunk-YBLDE5CG.js +42 -0
  83. package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
  84. package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
  85. package/dist/class/class.codec.js +12 -9
  86. package/dist/class/class.parser.js +11 -8
  87. package/dist/class/class.schema.d.ts +55 -3
  88. package/dist/class/class.schema.js +9 -7
  89. package/dist/class/class.types.d.ts +48 -3
  90. package/dist/condition/condition.codec.d.ts +9 -0
  91. package/dist/condition/condition.entity-type.d.ts +2 -0
  92. package/dist/condition/condition.parser.d.ts +13 -0
  93. package/dist/condition/condition.parser.js +7 -0
  94. package/dist/condition/condition.schema.d.ts +29 -0
  95. package/dist/condition/condition.types.d.ts +15 -0
  96. package/dist/condition/condition.types.js +0 -0
  97. package/dist/dnd/constants.d.ts +22 -0
  98. package/dist/dnd/constants.js +9 -3
  99. package/dist/dnd/formula-tags.js +2 -2
  100. package/dist/dnd/math.d.ts +26 -0
  101. package/dist/dnd/math.js +12 -2
  102. package/dist/dnd/prose-tags.js +1 -1
  103. package/dist/dnd/resource-formula.d.ts +36 -10
  104. package/dist/dnd/resource-formula.js +10 -155
  105. package/dist/dnd/srd-tag-converter.js +3 -3
  106. package/dist/dnd/tag-grammar.js +1 -1
  107. package/dist/dnd/warn-once.d.ts +2 -0
  108. package/dist/dnd/warn-once.js +8 -0
  109. package/dist/entities/base-item-resolver.js +2 -2
  110. package/dist/entities/slug.d.ts +13 -0
  111. package/dist/entities/slug.js +5 -3
  112. package/dist/entities/wikilink-display.d.ts +3 -0
  113. package/dist/entities/wikilink-display.js +10 -0
  114. package/dist/feat/feat.category-codes.d.ts +32 -0
  115. package/dist/feat/feat.category-codes.js +14 -0
  116. package/dist/feat/feat.codec.js +7 -5
  117. package/dist/feat/feat.parser.js +6 -4
  118. package/dist/feat/feat.schema.d.ts +239 -0
  119. package/dist/feat/feat.schema.js +5 -3
  120. package/dist/feat/feat.types.d.ts +37 -1
  121. package/dist/index.js +2033 -6907
  122. package/dist/item/item.codec.js +4 -3
  123. package/dist/item/item.enrichment.js +4 -4
  124. package/dist/item/item.parser.js +3 -2
  125. package/dist/item/item.schema.d.ts +69 -3
  126. package/dist/item/item.schema.js +2 -1
  127. package/dist/item/item.types.d.ts +69 -3
  128. package/dist/monster/monster.codec.d.ts +7 -6
  129. package/dist/monster/monster.enrichment.js +4 -4
  130. package/dist/monster/monster.format.d.ts +135 -0
  131. package/dist/monster/monster.format.js +78 -0
  132. package/dist/monster/monster.parser.d.ts +6 -1
  133. package/dist/monster/monster.parser.js +10 -1
  134. package/dist/monster/monster.schema.d.ts +369 -0
  135. package/dist/monster/monster.schema.js +34 -0
  136. package/dist/monster/monster.types.d.ts +200 -14
  137. package/dist/optional-feature/optional-feature.codec.js +6 -5
  138. package/dist/optional-feature/optional-feature.parser.js +5 -4
  139. package/dist/optional-feature/optional-feature.schema.d.ts +185 -0
  140. package/dist/optional-feature/optional-feature.schema.js +4 -3
  141. package/dist/pack.d.ts +1 -1
  142. package/dist/pc/conditions.constants.d.ts +0 -1
  143. package/dist/pc/conditions.constants.js +1 -3
  144. package/dist/pc/decision-recognizer.js +1 -1
  145. package/dist/pc/pc.additional-spells.d.ts +47 -0
  146. package/dist/pc/pc.additional-spells.js +23 -0
  147. package/dist/pc/pc.asi-flatten.d.ts +18 -0
  148. package/dist/pc/pc.decision-engine.d.ts +105 -17
  149. package/dist/pc/pc.decision-engine.js +28 -12
  150. package/dist/pc/pc.defense-normalize.d.ts +11 -0
  151. package/dist/pc/pc.defense-normalize.js +6 -0
  152. package/dist/pc/pc.equipment.d.ts +31 -2
  153. package/dist/pc/pc.equipment.js +12 -8
  154. package/dist/pc/pc.feature-effects.d.ts +234 -11
  155. package/dist/pc/pc.feature-effects.js +21 -5
  156. package/dist/pc/pc.parser.js +2 -2
  157. package/dist/pc/pc.pools.d.ts +11 -3
  158. package/dist/pc/pc.pools.js +9 -13
  159. package/dist/pc/pc.proficiencies.d.ts +54 -29
  160. package/dist/pc/pc.proficiencies.js +74 -95
  161. package/dist/pc/pc.proficiency-grants.d.ts +58 -0
  162. package/dist/pc/pc.proficiency-normalize.d.ts +24 -0
  163. package/dist/pc/pc.proficiency-normalize.js +12 -0
  164. package/dist/pc/pc.proficiency-query.d.ts +13 -0
  165. package/dist/pc/pc.proficiency-query.js +1 -1
  166. package/dist/pc/pc.recalc.d.ts +69 -14
  167. package/dist/pc/pc.recalc.js +261 -122
  168. package/dist/pc/pc.resolver.d.ts +34 -8
  169. package/dist/pc/pc.resolver.js +27 -12
  170. package/dist/pc/pc.resource-seed.d.ts +3 -2
  171. package/dist/pc/pc.resource-seed.js +19 -17
  172. package/dist/pc/pc.resources.d.ts +87 -0
  173. package/dist/pc/pc.resources.js +21 -0
  174. package/dist/pc/pc.rest.d.ts +10 -1
  175. package/dist/pc/pc.rest.js +66 -12
  176. package/dist/pc/pc.schema.d.ts +139 -3
  177. package/dist/pc/pc.schema.js +4 -2
  178. package/dist/pc/pc.slotting.js +3 -3
  179. package/dist/pc/pc.spellcasting.d.ts +75 -6
  180. package/dist/pc/pc.spellcasting.js +16 -6
  181. package/dist/pc/pc.table-column.d.ts +23 -0
  182. package/dist/pc/pc.table-column.js +13 -3
  183. package/dist/pc/pc.types.d.ts +251 -12
  184. package/dist/pc/pool-layout.d.ts +47 -0
  185. package/dist/pc/pool-layout.js +16 -0
  186. package/dist/pc/roll-scope.d.ts +2 -0
  187. package/dist/pc/roll-scope.js +8 -0
  188. package/dist/pc/roll-tag-labels.d.ts +40 -0
  189. package/dist/pc/roll-tag-labels.js +17 -0
  190. package/dist/pc/spell-source.d.ts +21 -0
  191. package/dist/pc/spell-source.js +13 -0
  192. package/dist/race/race.codec.js +9 -7
  193. package/dist/race/race.parser.js +8 -6
  194. package/dist/race/race.schema.d.ts +51 -1
  195. package/dist/race/race.schema.js +8 -5
  196. package/dist/race/race.structural.d.ts +7 -0
  197. package/dist/race/race.structural.js +6 -0
  198. package/dist/race/race.types.d.ts +20 -0
  199. package/dist/schemas/attack-schema.d.ts +5 -0
  200. package/dist/schemas/caster-type-schema.d.ts +14 -0
  201. package/dist/schemas/caster-type-schema.js +6 -0
  202. package/dist/schemas/choice-schema.js +2 -2
  203. package/dist/schemas/entity-extras-schema.d.ts +53 -0
  204. package/dist/schemas/entity-extras-schema.js +10 -0
  205. package/dist/schemas/equipment-grant-schema.d.ts +2 -0
  206. package/dist/schemas/equipment-grant-schema.js +1 -1
  207. package/dist/schemas/feature-alias.d.ts +34 -0
  208. package/dist/schemas/feature-effect-schema.d.ts +133 -0
  209. package/dist/schemas/feature-effect-schema.js +1 -1
  210. package/dist/schemas/feature-schema.d.ts +8 -0
  211. package/dist/schemas/feature-schema.js +6 -4
  212. package/dist/schemas/resource-schema.d.ts +43 -0
  213. package/dist/schemas/resource-schema.js +1 -1
  214. package/dist/schemas/selection-pool-schema.d.ts +2 -0
  215. package/dist/schemas/selection-pool-schema.js +1 -1
  216. package/dist/spell/spell.access.js +23 -3
  217. package/dist/spell/spell.codec.js +4 -3
  218. package/dist/spell/spell.enrichment.js +4 -4
  219. package/dist/spell/spell.parser.d.ts +30 -0
  220. package/dist/spell/spell.parser.js +9 -2
  221. package/dist/spell/spell.scaling.d.ts +27 -6
  222. package/dist/spell/spell.scaling.js +25 -6
  223. package/dist/spell/spell.schema.d.ts +44 -2
  224. package/dist/spell/spell.schema.js +2 -1
  225. package/dist/spell/spell.types.d.ts +14 -0
  226. package/dist/subclass/subclass.codec.d.ts +1 -1
  227. package/dist/subclass/subclass.codec.js +11 -8
  228. package/dist/subclass/subclass.parser.js +10 -7
  229. package/dist/subclass/subclass.schema.d.ts +54 -7
  230. package/dist/subclass/subclass.schema.js +8 -6
  231. package/dist/subclass/subclass.types.d.ts +20 -2
  232. package/dist/types/choice.d.ts +53 -2
  233. package/dist/types/choice.js +13 -1
  234. package/dist/types/equipment-grant.d.ts +8 -1
  235. package/dist/types/feature-effect.d.ts +85 -23
  236. package/dist/types/feature.d.ts +70 -1
  237. package/dist/types/optional-feature.types.d.ts +28 -0
  238. package/dist/types/resource.d.ts +21 -1
  239. package/dist/types/selection-pool.d.ts +17 -2
  240. package/dist/weapon/weapon.classify.js +2 -2
  241. package/dist/weapon/weapon.codec.js +4 -3
  242. package/dist/weapon/weapon.parser.js +3 -2
  243. package/dist/weapon/weapon.schema.d.ts +4 -0
  244. package/dist/weapon/weapon.schema.js +2 -1
  245. package/dist/weapon/weapon.types.d.ts +8 -0
  246. package/package.json +2 -2
  247. package/dist/chunk-5XUXXAQJ.js +0 -30
  248. package/dist/chunk-7P65Q426.js +0 -158
  249. package/dist/chunk-7TEK5KK7.js +0 -49
  250. package/dist/chunk-AIRFC5NQ.js +0 -143
  251. package/dist/chunk-CZPMTQOY.js +0 -68
  252. package/dist/chunk-N2JE7BWL.js +0 -81
  253. package/dist/chunk-NXR3BD2V.js +0 -90
  254. package/dist/chunk-O5EYMKFH.js +0 -6
  255. package/dist/chunk-Q5K6LWBZ.js +0 -45
  256. package/dist/chunk-TNUFPIXI.js +0 -1110
  257. package/dist/chunk-TZK36BU7.js +0 -38
  258. package/dist/chunk-W7HWMMBF.js +0 -46
  259. package/dist/chunk-Y4I74YEG.js +0 -33
@@ -2,16 +2,23 @@ import { z } from "zod";
2
2
  export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
3
  kind: z.ZodLiteral<"initiative-bonus">;
4
4
  value: z.ZodNumber;
5
+ condition: z.ZodOptional<z.ZodString>;
6
+ subject: z.ZodOptional<z.ZodString>;
5
7
  }, z.core.$strip>, z.ZodObject<{
6
8
  kind: z.ZodLiteral<"immune-condition">;
7
9
  condition: z.ZodString;
8
10
  while: z.ZodOptional<z.ZodString>;
11
+ subject: z.ZodOptional<z.ZodString>;
9
12
  }, z.core.$strip>, z.ZodObject<{
10
13
  kind: z.ZodLiteral<"resistance">;
11
14
  damage_type: z.ZodString;
15
+ condition: z.ZodOptional<z.ZodString>;
16
+ subject: z.ZodOptional<z.ZodString>;
12
17
  }, z.core.$strip>, z.ZodObject<{
13
18
  kind: z.ZodLiteral<"hp-per-level-bonus">;
14
19
  value: z.ZodNumber;
20
+ condition: z.ZodOptional<z.ZodString>;
21
+ subject: z.ZodOptional<z.ZodString>;
15
22
  }, z.core.$strip>, z.ZodObject<{
16
23
  kind: z.ZodLiteral<"speed-bonus">;
17
24
  mode: z.ZodEnum<{
@@ -23,6 +30,21 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
23
30
  }>;
24
31
  value: z.ZodNumber;
25
32
  set: z.ZodOptional<z.ZodBoolean>;
33
+ scales_at: z.ZodOptional<z.ZodArray<z.ZodObject<{
34
+ level: z.ZodNumber;
35
+ value: z.ZodNumber;
36
+ }, z.core.$strip>>>;
37
+ condition: z.ZodOptional<z.ZodString>;
38
+ subject: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ kind: z.ZodLiteral<"attunement-limit">;
41
+ value: z.ZodNumber;
42
+ scales_at: z.ZodOptional<z.ZodArray<z.ZodObject<{
43
+ level: z.ZodNumber;
44
+ value: z.ZodNumber;
45
+ }, z.core.$strip>>>;
46
+ condition: z.ZodOptional<z.ZodString>;
47
+ subject: z.ZodOptional<z.ZodString>;
26
48
  }, z.core.$strip>, z.ZodObject<{
27
49
  kind: z.ZodLiteral<"sense">;
28
50
  type: z.ZodEnum<{
@@ -32,6 +54,8 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
32
54
  truesight: "truesight";
33
55
  }>;
34
56
  range: z.ZodNumber;
57
+ condition: z.ZodOptional<z.ZodString>;
58
+ subject: z.ZodOptional<z.ZodString>;
35
59
  }, z.core.$strip>, z.ZodObject<{
36
60
  kind: z.ZodLiteral<"apply-condition">;
37
61
  condition: z.ZodString;
@@ -41,6 +65,7 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
41
65
  ability: z.ZodString;
42
66
  timing: z.ZodString;
43
67
  }, z.core.$strip>>;
68
+ subject: z.ZodOptional<z.ZodString>;
44
69
  }, z.core.$strip>, z.ZodObject<{
45
70
  kind: z.ZodLiteral<"damage-bonus">;
46
71
  damage_type: z.ZodString;
@@ -51,6 +76,7 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
51
76
  all: "all";
52
77
  }>>;
53
78
  condition: z.ZodOptional<z.ZodString>;
79
+ subject: z.ZodOptional<z.ZodString>;
54
80
  }, z.core.$strip>, z.ZodObject<{
55
81
  kind: z.ZodLiteral<"proficiency">;
56
82
  proficiency_type: z.ZodEnum<{
@@ -62,10 +88,15 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
62
88
  armor: "armor";
63
89
  }>;
64
90
  value: z.ZodString;
91
+ expertise: z.ZodOptional<z.ZodBoolean>;
92
+ condition: z.ZodOptional<z.ZodString>;
93
+ subject: z.ZodOptional<z.ZodString>;
65
94
  }, z.core.$strip>, z.ZodObject<{
66
95
  kind: z.ZodLiteral<"ac-bonus">;
67
96
  value: z.ZodNumber;
68
97
  requires_armor: z.ZodOptional<z.ZodBoolean>;
98
+ condition: z.ZodOptional<z.ZodString>;
99
+ subject: z.ZodOptional<z.ZodString>;
69
100
  }, z.core.$strip>, z.ZodObject<{
70
101
  kind: z.ZodLiteral<"unarmored-ac">;
71
102
  abilities: z.ZodArray<z.ZodEnum<{
@@ -78,6 +109,23 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
78
109
  }>>;
79
110
  base: z.ZodOptional<z.ZodNumber>;
80
111
  allow_shield: z.ZodOptional<z.ZodBoolean>;
112
+ condition: z.ZodOptional<z.ZodString>;
113
+ subject: z.ZodOptional<z.ZodString>;
114
+ }, z.core.$strip>, z.ZodObject<{
115
+ kind: z.ZodLiteral<"unarmed-strike">;
116
+ dice: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
117
+ column: z.ZodString;
118
+ }, z.core.$strip>]>>;
119
+ abilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
120
+ str: "str";
121
+ dex: "dex";
122
+ con: "con";
123
+ int: "int";
124
+ wis: "wis";
125
+ cha: "cha";
126
+ }>>>;
127
+ condition: z.ZodOptional<z.ZodString>;
128
+ subject: z.ZodOptional<z.ZodString>;
81
129
  }, z.core.$strip>, z.ZodObject<{
82
130
  kind: z.ZodLiteral<"weapon-ability">;
83
131
  ability: z.ZodUnion<readonly [z.ZodEnum<{
@@ -89,22 +137,34 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
89
137
  cha: "cha";
90
138
  }>, z.ZodLiteral<"spellcasting">]>;
91
139
  weapons: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"chosen">, z.ZodString, z.ZodArray<z.ZodString>]>>;
140
+ condition: z.ZodOptional<z.ZodString>;
141
+ subject: z.ZodOptional<z.ZodString>;
92
142
  }, z.core.$strip>, z.ZodObject<{
93
143
  kind: z.ZodLiteral<"roll-modifier">;
94
144
  mode: z.ZodEnum<{
95
145
  advantage: "advantage";
96
146
  disadvantage: "disadvantage";
147
+ reroll: "reroll";
148
+ "add-d4": "add-d4";
97
149
  }>;
98
150
  roll: z.ZodEnum<{
99
151
  "saving-throw": "saving-throw";
100
152
  "ability-check": "ability-check";
101
153
  attack: "attack";
154
+ any: "any";
102
155
  }>;
103
156
  scope: z.ZodOptional<z.ZodString>;
104
157
  condition: z.ZodOptional<z.ZodString>;
158
+ subject: z.ZodOptional<z.ZodString>;
105
159
  }, z.core.$strip>, z.ZodObject<{
106
160
  kind: z.ZodLiteral<"extra-attack">;
107
161
  count: z.ZodNumber;
162
+ scales_at: z.ZodOptional<z.ZodArray<z.ZodObject<{
163
+ level: z.ZodNumber;
164
+ count: z.ZodNumber;
165
+ }, z.core.$strip>>>;
166
+ condition: z.ZodOptional<z.ZodString>;
167
+ subject: z.ZodOptional<z.ZodString>;
108
168
  }, z.core.$strip>, z.ZodObject<{
109
169
  kind: z.ZodLiteral<"crit-range">;
110
170
  min_roll: z.ZodNumber;
@@ -114,6 +174,7 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
114
174
  all: "all";
115
175
  }>>;
116
176
  condition: z.ZodOptional<z.ZodString>;
177
+ subject: z.ZodOptional<z.ZodString>;
117
178
  }, z.core.$strip>, z.ZodObject<{
118
179
  kind: z.ZodLiteral<"reroll-damage">;
119
180
  max_reroll: z.ZodNumber;
@@ -123,9 +184,81 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
123
184
  all: "all";
124
185
  }>>;
125
186
  once_per_die: z.ZodOptional<z.ZodBoolean>;
187
+ condition: z.ZodOptional<z.ZodString>;
188
+ subject: z.ZodOptional<z.ZodString>;
126
189
  }, z.core.$strip>, z.ZodObject<{
127
190
  kind: z.ZodLiteral<"attack-rule">;
128
191
  flag: z.ZodEnum<{
129
192
  "no-ranged-in-melee-disadvantage": "no-ranged-in-melee-disadvantage";
130
193
  }>;
194
+ condition: z.ZodOptional<z.ZodString>;
195
+ subject: z.ZodOptional<z.ZodString>;
196
+ }, z.core.$strip>, z.ZodObject<{
197
+ kind: z.ZodLiteral<"immunity">;
198
+ damage_type: z.ZodString;
199
+ condition: z.ZodOptional<z.ZodString>;
200
+ subject: z.ZodOptional<z.ZodString>;
201
+ }, z.core.$strip>, z.ZodObject<{
202
+ kind: z.ZodLiteral<"vulnerability">;
203
+ damage_type: z.ZodString;
204
+ condition: z.ZodOptional<z.ZodString>;
205
+ subject: z.ZodOptional<z.ZodString>;
206
+ }, z.core.$strip>, z.ZodObject<{
207
+ kind: z.ZodLiteral<"temp-hp">;
208
+ amount: z.ZodString;
209
+ condition: z.ZodOptional<z.ZodString>;
210
+ subject: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>, z.ZodObject<{
212
+ kind: z.ZodLiteral<"heal">;
213
+ amount: z.ZodString;
214
+ condition: z.ZodOptional<z.ZodString>;
215
+ subject: z.ZodOptional<z.ZodString>;
216
+ }, z.core.$strip>, z.ZodObject<{
217
+ kind: z.ZodLiteral<"ability-score-increase">;
218
+ abilities: z.ZodUnion<readonly [z.ZodLiteral<"chosen">, z.ZodArray<z.ZodEnum<{
219
+ str: "str";
220
+ dex: "dex";
221
+ con: "con";
222
+ int: "int";
223
+ wis: "wis";
224
+ cha: "cha";
225
+ }>>]>;
226
+ amount: z.ZodNumber;
227
+ choose: z.ZodNullable<z.ZodNumber>;
228
+ max: z.ZodNullable<z.ZodNumber>;
229
+ condition: z.ZodOptional<z.ZodString>;
230
+ subject: z.ZodOptional<z.ZodString>;
231
+ }, z.core.$strip>, z.ZodObject<{
232
+ kind: z.ZodLiteral<"extra-action">;
233
+ count: z.ZodNumber;
234
+ action_type: z.ZodEnum<{
235
+ action: "action";
236
+ "bonus-action": "bonus-action";
237
+ reaction: "reaction";
238
+ }>;
239
+ condition: z.ZodOptional<z.ZodString>;
240
+ subject: z.ZodOptional<z.ZodString>;
241
+ }, z.core.$strip>, z.ZodObject<{
242
+ kind: z.ZodLiteral<"save-outcome">;
243
+ ability: z.ZodUnion<readonly [z.ZodEnum<{
244
+ str: "str";
245
+ dex: "dex";
246
+ con: "con";
247
+ int: "int";
248
+ wis: "wis";
249
+ cha: "cha";
250
+ }>, z.ZodLiteral<"any">]>;
251
+ on_success: z.ZodEnum<{
252
+ none: "none";
253
+ half: "half";
254
+ full: "full";
255
+ }>;
256
+ on_failure: z.ZodEnum<{
257
+ none: "none";
258
+ half: "half";
259
+ full: "full";
260
+ }>;
261
+ applies_to: z.ZodNullable<z.ZodString>;
262
+ condition: z.ZodOptional<z.ZodString>;
263
+ subject: z.ZodOptional<z.ZodString>;
131
264
  }, z.core.$strip>], "kind">;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  featureEffectSchema
3
- } from "../chunk-NXR3BD2V.js";
3
+ } from "../chunk-X3D6LXUU.js";
4
4
  export {
5
5
  featureEffectSchema
6
6
  };
@@ -1,2 +1,10 @@
1
1
  import { z } from "zod";
2
+ import type { Feature } from "../types/feature.js";
3
+ /**
4
+ * The feature OBJECT, declared once (R4-G6 §4.2). Typed against the `Feature` interface so a wrong leaf fails
5
+ * `tsc`; exported UN-REFINED for the monster schema, whose name-only authored traits the hand parser accepted.
6
+ * The recursion runs through the REFINED schema so a nested class sub_feature keeps the description-or-entries
7
+ * rule; the refined `featureSchema` below keeps its exported `z.ZodType<unknown>` for every other root.
8
+ */
9
+ export declare const featureObjectSchema: z.ZodType<Feature>;
2
10
  export declare const featureSchema: z.ZodType<unknown>;
@@ -1,10 +1,12 @@
1
1
  import {
2
+ featureObjectSchema,
2
3
  featureSchema
3
- } from "../chunk-CZPMTQOY.js";
4
+ } from "../chunk-W74BCA7V.js";
4
5
  import "../chunk-WYGD2UGN.js";
5
- import "../chunk-PZOWBI3B.js";
6
- import "../chunk-NXSWH3AE.js";
7
- import "../chunk-NXR3BD2V.js";
6
+ import "../chunk-YLL2QXY2.js";
7
+ import "../chunk-IWRVOCT5.js";
8
+ import "../chunk-X3D6LXUU.js";
8
9
  export {
10
+ featureObjectSchema,
9
11
  featureSchema
10
12
  };
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  declare const resetTriggerEnum: z.ZodEnum<{
3
3
  "short-rest": "short-rest";
4
4
  "long-rest": "long-rest";
5
+ either: "either";
5
6
  dawn: "dawn";
6
7
  dusk: "dusk";
7
8
  turn: "turn";
@@ -30,6 +31,7 @@ export declare const resourceSchema: z.ZodObject<{
30
31
  reset: z.ZodEnum<{
31
32
  "short-rest": "short-rest";
32
33
  "long-rest": "long-rest";
34
+ either: "either";
33
35
  dawn: "dawn";
34
36
  dusk: "dusk";
35
37
  turn: "turn";
@@ -55,14 +57,53 @@ export declare const resourceSchema: z.ZodObject<{
55
57
  reset: z.ZodEnum<{
56
58
  "short-rest": "short-rest";
57
59
  "long-rest": "long-rest";
60
+ either: "either";
58
61
  dawn: "dawn";
59
62
  dusk: "dusk";
60
63
  turn: "turn";
61
64
  round: "round";
62
65
  custom: "custom";
63
66
  }>;
67
+ restores: z.ZodOptional<z.ZodEnum<{
68
+ uses: "uses";
69
+ "spell-slots": "spell-slots";
70
+ }>>;
64
71
  }, z.core.$strip>>>;
65
72
  }, z.core.$strip>;
73
+ /** A feature's / optional feature's resource spend.
74
+ *
75
+ * `amount` is the MINIMUM spend. When `amount_max` is present the spend is a
76
+ * RANGE (`amount` .. `amount_max`). Readers of `consumes.resource`, re-measured
77
+ * 2026-09-05 across both repos' `src` after plugin task T4 landed: the ENGINE still has
78
+ * exactly one, `pc/pc.pools.ts`'s pool vote (R4-G4 §4.2.3, whose owner-aware form T2 shipped;
79
+ * the `consumes.resource` key itself PREDATES T2, measured on `821f80d`), which reads the
80
+ * id to pick `ResolvedPool.resource` and never spends it; the PLUGIN now has SEVEN FUNCTIONS over
81
+ * EIGHT code lines in four files (the unit matters: `grep -rn "consumes\.resource\|consumes?\.resource"
82
+ * packages/obsidian/src` returns NINE lines, one of them docblock prose, and `consumeCost` reads the
83
+ * field on two of the eight). They are: `renderSpendControl` (`components/actions/spend-control.ts`),
84
+ * which SPENDS it; the four row sites that gate that call, `PoolTab.row`, `PoolTab.grantedRow` and
85
+ * `PoolTab.blockCard` (`components/pool-tab.ts`) and `renderBoonRow`
86
+ * (`components/actions/boon-rows.ts`). Their gates, measured 2026-09-05 with `grep -n` on
87
+ * `pool-tab.ts`, are NOT the same test, because their callers differ: `row` is gated on the entry
88
+ * being SELECTED (`renderSpellLike` sends it every available candidate), `blockCard` on the entry
89
+ * being GRANTED OR SELECTED (`renderBlocks` sends it the available candidates, then the stranded
90
+ * picks, then the grants), and `grantedRow` is UNCONDITIONAL because it is reached only by the loop
91
+ * over `pool.grants`, as is `renderBoonRow`, which the plugin's `section-renderer.ts` reaches only
92
+ * with a `kind` of "selected" or "granted". One rule, KNOWN entries only, expressed four ways;
93
+ * `renderFeatureRow` (`components/actions/feature-rows.ts`), whose owner-and-spender rule
94
+ * decides between the row slot, the expand card and no control at all; and `consumeCost`
95
+ * (`components/pool-tab.ts`), the ONE Cost label the row sub-line and the block card now
96
+ * share, which prints the resource's NAME from the index and keeps the raw id only as the
97
+ * fallback for an id the character does not own (it no longer singularizes or capitalizes
98
+ * it). The field IS spent as of R4-G4 T4: §3's control spends `amount` exactly through
99
+ * `CharacterEditState.spendFeatureUse`, the clamped quantity-taking primitive the plugin
100
+ * already had. What R4-G4 does NOT do (§15): the HOW-MUCH UI for a range spend
101
+ * and its validation rule stay G8, and the converter un-withhold that would emit
102
+ * `amount_max` at all is a G7 handoff. So `amount_max` stays DECLARED here only, with
103
+ * zero emitted carriers, and the refine is undefined-safe by construction so the
104
+ * corpus that ships without the key keeps parsing: 294 `Feature.consumes` carriers
105
+ * over 161 documents, plus 70 `OptionalFeature.consumes` documents (R4-G3a §9; an
106
+ * unguarded refine refuses all 231, measured). */
66
107
  export declare const resourceConsumptionSchema: z.ZodObject<{
67
108
  source: z.ZodOptional<z.ZodEnum<{
68
109
  resource: "resource";
@@ -72,6 +113,7 @@ export declare const resourceConsumptionSchema: z.ZodObject<{
72
113
  resource: z.ZodOptional<z.ZodString>;
73
114
  column: z.ZodOptional<z.ZodString>;
74
115
  amount: z.ZodNumber;
116
+ amount_max: z.ZodOptional<z.ZodNumber>;
75
117
  expend_condition: z.ZodOptional<z.ZodEnum<{
76
118
  roll_succeeds: "roll_succeeds";
77
119
  roll_fails: "roll_fails";
@@ -83,6 +125,7 @@ export declare const resourceConsumptionSchema: z.ZodObject<{
83
125
  reset: z.ZodEnum<{
84
126
  "short-rest": "short-rest";
85
127
  "long-rest": "long-rest";
128
+ either: "either";
86
129
  dawn: "dawn";
87
130
  dusk: "dusk";
88
131
  turn: "turn";
@@ -3,7 +3,7 @@ import {
3
3
  resetTriggerEnum,
4
4
  resourceConsumptionSchema,
5
5
  resourceSchema
6
- } from "../chunk-PZOWBI3B.js";
6
+ } from "../chunk-YLL2QXY2.js";
7
7
  export {
8
8
  actionCostEnum,
9
9
  resetTriggerEnum,
@@ -29,6 +29,8 @@ export declare const tabDeclSchema: z.ZodObject<{
29
29
  layout: z.ZodOptional<z.ZodEnum<{
30
30
  "spell-like": "spell-like";
31
31
  blocks: "blocks";
32
+ "dice-pool": "dice-pool";
33
+ "point-pool": "point-pool";
32
34
  }>>;
33
35
  }, z.core.$strip>;
34
36
  }, z.core.$strip>;
@@ -2,7 +2,7 @@ import {
2
2
  poolGrantSchema,
3
3
  selectionPoolSchema,
4
4
  tabDeclSchema
5
- } from "../chunk-4TIJKN6O.js";
5
+ } from "../chunk-23LZLBJK.js";
6
6
  export {
7
7
  poolGrantSchema,
8
8
  selectionPoolSchema,
@@ -3,10 +3,29 @@ import {
3
3
  } from "../chunk-VTTA2ALZ.js";
4
4
 
5
5
  // src/spell/spell.access.ts
6
+ var LISTED_CLASS_NAMES = /* @__PURE__ */ new WeakMap();
7
+ function listedClassNames(registry) {
8
+ const count = registry.count();
9
+ const cached = LISTED_CLASS_NAMES.get(registry);
10
+ if (cached && cached.count === count) return cached.names;
11
+ const names = /* @__PURE__ */ new Set();
12
+ for (const e of registry.search("", "spell", Number.POSITIVE_INFINITY)) {
13
+ const classes = e.data.classes;
14
+ if (!Array.isArray(classes)) continue;
15
+ for (const c of classes) names.add(baseClassName(String(c)));
16
+ }
17
+ LISTED_CLASS_NAMES.set(registry, { count, names });
18
+ return names;
19
+ }
6
20
  function classSpellCandidates(registry, classSlugs, maxLevel, knownSlugs, showAll = false, query = "") {
7
- const all = registry.search(query, "spell", 1e3);
21
+ const all = registry.search(query, "spell", Number.POSITIVE_INFINITY);
8
22
  const q = query.toLowerCase();
9
23
  const classSet = new Set(classSlugs.map((s) => baseClassName(s)));
24
+ let unlistable = false;
25
+ if (!showAll && classSet.size > 0) {
26
+ const listed = listedClassNames(registry);
27
+ unlistable = [...classSet].some((n) => !listed.has(n));
28
+ }
10
29
  return all.filter((e) => !knownSlugs.has(e.slug)).map((e) => {
11
30
  var _a;
12
31
  const entity = e.data;
@@ -15,9 +34,10 @@ function classSpellCandidates(registry, classSlugs, maxLevel, knownSlugs, showAl
15
34
  var _a;
16
35
  if (q && !c.name.toLowerCase().includes(q)) return false;
17
36
  if (showAll) return true;
37
+ if (c.level > maxLevel) return false;
38
+ if (unlistable) return true;
18
39
  const classes = ((_a = c.entity.classes) != null ? _a : []).map((x) => baseClassName(x));
19
- const inClass = classes.some((x) => classSet.has(x));
20
- return inClass && c.level <= maxLevel;
40
+ return classes.some((x) => classSet.has(x));
21
41
  }).sort((a, b) => a.level - b.level || a.name.localeCompare(b.name));
22
42
  }
23
43
  export {
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  spellCodec
3
- } from "../chunk-24GFQU7T.js";
4
- import "../chunk-N2JE7BWL.js";
5
- import "../chunk-Y4I74YEG.js";
3
+ } from "../chunk-JSZ4H6AQ.js";
4
+ import "../chunk-OZP6JFGT.js";
5
+ import "../chunk-VQAXTIBW.js";
6
+ import "../chunk-UA5KS2PL.js";
6
7
  export {
7
8
  spellCodec
8
9
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  enrichSpell
3
- } from "../chunk-GZ46OVGZ.js";
4
- import "../chunk-RAWJTA45.js";
5
- import "../chunk-NAEPSZAM.js";
6
- import "../chunk-WP2CX2JO.js";
3
+ } from "../chunk-WSVMLNTO.js";
4
+ import "../chunk-DEEHHLAP.js";
5
+ import "../chunk-PDJSUH24.js";
6
+ import "../chunk-WELIKLZF.js";
7
7
  export {
8
8
  enrichSpell
9
9
  };
@@ -1,3 +1,33 @@
1
1
  import { Spell } from "./spell.types.js";
2
2
  import { ParseResult } from "@archivist-gg/core";
3
+ /**
4
+ * §3.3 · collapse the converter's structured `components` object to the corpus's own string form
5
+ * (`V, S, M (a coin), R`), leaving a string input byte-unchanged. Letter order is V, S, M, R;
6
+ * `m` object -> `M (<text>)` (the text already carries the cost prose), `m` string -> `M (<value>)`,
7
+ * `m: true` -> a bare `M`. A boolean flag contributes its letter only when it is exactly `true`.
8
+ * Casing follows the 862 string-form carriers (uppercase letters); `R` has no precedent among them
9
+ * and is an invented-but-decided literal (Gate 0 B-5).
10
+ *
11
+ * The parameter is `unknown` on purpose: `spellComponentsObjectSchema` stays local and unexported,
12
+ * so this function narrows structurally instead of importing the schema's type. `toStringSafe` is
13
+ * the unreachable-shape fallback (the schema has already accepted the value by the time we run).
14
+ */
15
+ export declare function normalizeSpellComponents(value: unknown): string;
16
+ /**
17
+ * §3.3 · collapse the converter's structured `duration` array to the corpus's own lowercase string
18
+ * form (`until dispelled`, `up to 1 hour`), leaving a string input byte-unchanged. Concentration is
19
+ * NEVER synthesised here — the separate `concentration` boolean drives the sheet's `Conc · ` prefix.
20
+ * Zero docs carry more than one entry; the `; ` join is the defensive path for the day one does.
21
+ */
22
+ export declare function normalizeSpellDuration(value: unknown): string;
23
+ /**
24
+ * R4-G7 §7.5 · the RESOLVE-time twin of the two normalisations `parseSpell` performs below. The PC pipeline
25
+ * reads RAW registry entities (`reg.data as unknown as Spell`), so a converter spell reaches the sheet with a
26
+ * structured `components` object and `duration` array unless it passes through here; `componentLetters`
27
+ * (the sheet) and the add drawer's duration cell both read strings. The `!= null` guards MIRROR `parseSpell`'s
28
+ * own, so a spell that authors neither key keeps neither. Lives HERE, beside the normalisers, and not in
29
+ * `pc.resolver.ts`, which already imports `pc.additional-spells` and would make the two a value cycle
30
+ * [G2-I-2]. Returns a fresh object; the shared registry entity is never mutated.
31
+ */
32
+ export declare function mirrorSpellShapes(entity: Spell): Spell;
3
33
  export declare function parseSpell(source: string): ParseResult<Spell>;
@@ -1,7 +1,14 @@
1
1
  import {
2
+ mirrorSpellShapes,
3
+ normalizeSpellComponents,
4
+ normalizeSpellDuration,
2
5
  parseSpell
3
- } from "../chunk-N2JE7BWL.js";
4
- import "../chunk-Y4I74YEG.js";
6
+ } from "../chunk-OZP6JFGT.js";
7
+ import "../chunk-VQAXTIBW.js";
8
+ import "../chunk-UA5KS2PL.js";
5
9
  export {
10
+ mirrorSpellShapes,
11
+ normalizeSpellComponents,
12
+ normalizeSpellDuration,
6
13
  parseSpell
7
14
  };
@@ -1,14 +1,35 @@
1
1
  import type { Spell } from "./spell.types.js";
2
2
  /** A spell repeats under higher levels only if it has a real upcast benefit. */
3
3
  export declare function spellScales(spell: Spell): boolean;
4
+ /** The `casting_options` field a scaled value was read from (R4-G7 T8 RIDER-16). */
5
+ export type SpellEffectField = "damage_roll" | "target_count" | "duration" | "desc";
6
+ /** A scaled value and the FIELD it came from, so a renderer decides where it prints from the field. */
7
+ export interface SpellEffectParts {
8
+ field: SpellEffectField;
9
+ /** As printed: the roll, `"<N> targets"`, the duration, or the authored sentence verbatim. */
10
+ value: string;
11
+ }
4
12
  /**
5
- * At-a-glance scaled effect for casting `spell` with a slot of `slotLevel`,
6
- * read from structured `casting_options` (`type: "slot_level_<N>"`). Returns
7
- * null when absent or untrustworthy. `damage_roll` is shown as-is; a
8
- * `target_count` that equals the slot level is the known SRD-2014 bad encoding
9
- * (e.g. Magic Missile 2nd->2 instead of 4) and is suppressed. This errs toward
10
- * showing nothing rather than a wrong number.
13
+ * At-a-glance scaled effect for casting a LEVELLED `spell` with a slot of `slotLevel`,
14
+ * read from structured `casting_options` (`type: "slot_level_<N>"`), WITH the field it
15
+ * came from. Returns null when absent or untrustworthy. The FIRST present field wins, in
16
+ * this order: `damage_roll`, `target_count`, `duration`, `desc` (so an option carrying a
17
+ * roll AND a sentence yields the roll). A `target_count` that equals the slot level is
18
+ * the known SRD-2014 bad encoding (e.g. Magic Missile 2nd->2 instead of 4) and is
19
+ * suppressed. This errs toward showing nothing rather than a wrong number.
11
20
  */
21
+ export declare function spellEffectPartsAtSlot(spell: Spell, slotLevel: number): SpellEffectParts | null;
22
+ /** The value of `spellEffectPartsAtSlot`, without its field. */
12
23
  export declare function spellEffectAtSlot(spell: Spell, slotLevel: number): string | null;
24
+ /**
25
+ * R4-G7 T8 RIDER-15 (F-NODICE (a)): a CANTRIP's damage roll at the character's total level, read from structured
26
+ * `casting_options` (`type: "player_level_<N>"`). The roll of the HIGHEST `N <= characterLevel` wins: SRD 5e authors
27
+ * one option per level from 5 to 20, SRD 2024 and the converter author only 5 / 11 / 17. An option with no roll or an
28
+ * EMPTY one never qualifies (SRD 5e Acid Splash and Poison Spray open with `player_level_2..4` carrying
29
+ * `damage_roll: ''`; Eldritch Blast 2024 authors `target_count` only). Null for a levelled spell, for a level that is
30
+ * not a finite number (a fixture-built `derived` omits `totalLevel`), and when nothing qualifies: no corpus authors
31
+ * `player_level_1`, so a cantrip's base roll below level 5 is not in the data and nothing is invented here.
32
+ */
33
+ export declare function spellEffectAtCharacterLevel(spell: Spell, characterLevel: number): string | null;
13
34
  /** Owned slot levels strictly above the spell's base level (scaling spells only). */
14
35
  export declare function upcastLevelsFor(spell: Spell, ownedSlotLevels: number[]): number[];
@@ -3,17 +3,34 @@ 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 spellEffectAtSlot(spell, slotLevel) {
7
- var _a, _b;
6
+ function spellEffectPartsAtSlot(spell, slotLevel) {
7
+ var _a;
8
8
  const opt = ((_a = spell.casting_options) != null ? _a : []).find((o) => o.type === `slot_level_${slotLevel}`);
9
9
  if (!opt) return null;
10
- if (opt.damage_roll) return opt.damage_roll;
10
+ if (opt.damage_roll) return { field: "damage_roll", value: opt.damage_roll };
11
11
  if (typeof opt.target_count === "number") {
12
12
  if (opt.target_count === slotLevel) return null;
13
- return `${opt.target_count} targets`;
13
+ return { field: "target_count", value: `${opt.target_count} targets` };
14
+ }
15
+ if (opt.duration) return { field: "duration", value: opt.duration };
16
+ return opt.desc != null ? { field: "desc", value: opt.desc } : null;
17
+ }
18
+ function spellEffectAtSlot(spell, slotLevel) {
19
+ var _a, _b;
20
+ return (_b = (_a = spellEffectPartsAtSlot(spell, slotLevel)) == null ? void 0 : _a.value) != null ? _b : null;
21
+ }
22
+ var PLAYER_LEVEL_TYPE = /^player_level_(\d+)$/;
23
+ function spellEffectAtCharacterLevel(spell, characterLevel) {
24
+ var _a, _b, _c;
25
+ if (((_a = spell.level) != null ? _a : 0) !== 0 || !Number.isFinite(characterLevel)) return null;
26
+ let best = null;
27
+ for (const opt of (_b = spell.casting_options) != null ? _b : []) {
28
+ const m = PLAYER_LEVEL_TYPE.exec(String((_c = opt.type) != null ? _c : ""));
29
+ if (!m || typeof opt.damage_roll !== "string" || opt.damage_roll.trim() === "") continue;
30
+ const n = Number(m[1]);
31
+ if (n <= characterLevel && (best === null || n > best.n)) best = { n, roll: opt.damage_roll };
14
32
  }
15
- if (opt.duration) return opt.duration;
16
- return (_b = opt.desc) != null ? _b : null;
33
+ return best ? best.roll : null;
17
34
  }
18
35
  function upcastLevelsFor(spell, ownedSlotLevels) {
19
36
  var _a;
@@ -22,7 +39,9 @@ function upcastLevelsFor(spell, ownedSlotLevels) {
22
39
  return ownedSlotLevels.filter((l) => l > base).sort((a, b) => a - b);
23
40
  }
24
41
  export {
42
+ spellEffectAtCharacterLevel,
25
43
  spellEffectAtSlot,
44
+ spellEffectPartsAtSlot,
26
45
  spellScales,
27
46
  upcastLevelsFor
28
47
  };