@archivist-gg/dnd5e 0.1.0

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 (322) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/SRD.md +37 -0
  3. package/README.md +65 -0
  4. package/dist/armor/armor.codec.d.ts +10 -0
  5. package/dist/armor/armor.codec.js +8 -0
  6. package/dist/armor/armor.entity-type.d.ts +2 -0
  7. package/dist/armor/armor.parser.d.ts +3 -0
  8. package/dist/armor/armor.parser.js +7 -0
  9. package/dist/armor/armor.schema.d.ts +25 -0
  10. package/dist/armor/armor.schema.js +6 -0
  11. package/dist/armor/armor.types.d.ts +26 -0
  12. package/dist/armor/armor.types.js +0 -0
  13. package/dist/background/background.codec.d.ts +9 -0
  14. package/dist/background/background.codec.js +11 -0
  15. package/dist/background/background.entity-type.d.ts +2 -0
  16. package/dist/background/background.parser.d.ts +3 -0
  17. package/dist/background/background.parser.js +10 -0
  18. package/dist/background/background.schema.d.ts +74 -0
  19. package/dist/background/background.schema.js +9 -0
  20. package/dist/background/background.types.d.ts +52 -0
  21. package/dist/background/background.types.js +0 -0
  22. package/dist/chunk-24GFQU7T.js +18 -0
  23. package/dist/chunk-3DZ74AKK.js +28 -0
  24. package/dist/chunk-3TM34RSJ.js +23 -0
  25. package/dist/chunk-3TRGRSCH.js +8 -0
  26. package/dist/chunk-4C2KOKLF.js +185 -0
  27. package/dist/chunk-4F6AIZ36.js +19 -0
  28. package/dist/chunk-4SSDYJS2.js +86 -0
  29. package/dist/chunk-4TIJKN6O.js +37 -0
  30. package/dist/chunk-537BHVSH.js +18 -0
  31. package/dist/chunk-5INR4NSL.js +18 -0
  32. package/dist/chunk-5XUXXAQJ.js +30 -0
  33. package/dist/chunk-656QCX4U.js +22 -0
  34. package/dist/chunk-66XXW2Z2.js +133 -0
  35. package/dist/chunk-6NK2MUD3.js +114 -0
  36. package/dist/chunk-6PXE7T7C.js +79 -0
  37. package/dist/chunk-7P65Q426.js +158 -0
  38. package/dist/chunk-A7T5L7SS.js +83 -0
  39. package/dist/chunk-AFKTJXRA.js +39 -0
  40. package/dist/chunk-B7UXKNLD.js +46 -0
  41. package/dist/chunk-BAXWWGFJ.js +45 -0
  42. package/dist/chunk-BH6AMZVY.js +25 -0
  43. package/dist/chunk-CDW7R2QT.js +62 -0
  44. package/dist/chunk-DABBCYTT.js +68 -0
  45. package/dist/chunk-DC74TZNA.js +46 -0
  46. package/dist/chunk-DNAJRMNN.js +68 -0
  47. package/dist/chunk-DRNZJNJP.js +19 -0
  48. package/dist/chunk-FEOB24KP.js +18 -0
  49. package/dist/chunk-FFULAF2P.js +63 -0
  50. package/dist/chunk-FUK7QSN5.js +19 -0
  51. package/dist/chunk-GIOH5JB5.js +19 -0
  52. package/dist/chunk-GJOI2GHP.js +25 -0
  53. package/dist/chunk-GZ46OVGZ.js +31 -0
  54. package/dist/chunk-HCP3GMHS.js +44 -0
  55. package/dist/chunk-IDTDACM6.js +19 -0
  56. package/dist/chunk-IKSMX4TN.js +0 -0
  57. package/dist/chunk-IXZXFFFW.js +269 -0
  58. package/dist/chunk-J2RYSZMQ.js +16 -0
  59. package/dist/chunk-JEYQU3JT.js +36 -0
  60. package/dist/chunk-LSLSG67V.js +31 -0
  61. package/dist/chunk-LWFTHJIE.js +24 -0
  62. package/dist/chunk-MDEJHMKK.js +52 -0
  63. package/dist/chunk-N2JE7BWL.js +81 -0
  64. package/dist/chunk-NAEPSZAM.js +88 -0
  65. package/dist/chunk-NXR3BD2V.js +90 -0
  66. package/dist/chunk-PKC77VZP.js +18 -0
  67. package/dist/chunk-PMADYMUI.js +19 -0
  68. package/dist/chunk-PTXBIDG7.js +63 -0
  69. package/dist/chunk-PZOWBI3B.js +49 -0
  70. package/dist/chunk-QQ5W2AZP.js +515 -0
  71. package/dist/chunk-QS5L5YTJ.js +24 -0
  72. package/dist/chunk-QYZV2MQA.js +97 -0
  73. package/dist/chunk-R2ZV233X.js +233 -0
  74. package/dist/chunk-RAWJTA45.js +271 -0
  75. package/dist/chunk-RSDRMH54.js +18 -0
  76. package/dist/chunk-RVYYKYFL.js +18 -0
  77. package/dist/chunk-SSXBYF3P.js +18 -0
  78. package/dist/chunk-TJCNX6UZ.js +521 -0
  79. package/dist/chunk-TZK36BU7.js +38 -0
  80. package/dist/chunk-UC4FE5X3.js +65 -0
  81. package/dist/chunk-WP2CX2JO.js +235 -0
  82. package/dist/chunk-WYGD2UGN.js +14 -0
  83. package/dist/chunk-XJNECUPT.js +31 -0
  84. package/dist/chunk-XURS6Q6Q.js +127 -0
  85. package/dist/chunk-Y4I74YEG.js +33 -0
  86. package/dist/chunk-Z4TL2V7S.js +18 -0
  87. package/dist/chunk-Z6GXV2GO.js +121 -0
  88. package/dist/chunk-ZLG6FQFB.js +237 -0
  89. package/dist/chunk-ZMR77DDL.js +18 -0
  90. package/dist/class/class.codec.d.ts +10 -0
  91. package/dist/class/class.codec.js +15 -0
  92. package/dist/class/class.entity-type.d.ts +2 -0
  93. package/dist/class/class.parser.d.ts +3 -0
  94. package/dist/class/class.parser.js +14 -0
  95. package/dist/class/class.schema.d.ts +202 -0
  96. package/dist/class/class.schema.js +13 -0
  97. package/dist/class/class.slug.d.ts +11 -0
  98. package/dist/class/class.slug.js +8 -0
  99. package/dist/class/class.types.d.ts +74 -0
  100. package/dist/class/class.types.js +0 -0
  101. package/dist/data-srd/index.generated.d.ts +7 -0
  102. package/dist/data-srd/index.generated.js +146 -0
  103. package/dist/dnd/constants.d.ts +16 -0
  104. package/dist/dnd/constants.js +36 -0
  105. package/dist/dnd/formula-tags.d.ts +16 -0
  106. package/dist/dnd/formula-tags.js +119 -0
  107. package/dist/dnd/math.d.ts +24 -0
  108. package/dist/dnd/math.js +35 -0
  109. package/dist/dnd/prose-tags.d.ts +16 -0
  110. package/dist/dnd/prose-tags.js +18 -0
  111. package/dist/dnd/resource-die.d.ts +6 -0
  112. package/dist/dnd/resource-die.js +17 -0
  113. package/dist/dnd/resource-formula.d.ts +41 -0
  114. package/dist/dnd/resource-formula.js +159 -0
  115. package/dist/dnd/srd-tag-converter.d.ts +44 -0
  116. package/dist/dnd/srd-tag-converter.js +12 -0
  117. package/dist/dnd/tag-grammar.d.ts +19 -0
  118. package/dist/dnd/tag-grammar.js +12 -0
  119. package/dist/encounter/encounter.ai-schema.d.ts +29 -0
  120. package/dist/encounter/encounter.ai-schema.js +8 -0
  121. package/dist/encounter/encounter.entity-type.d.ts +2 -0
  122. package/dist/encounter/encounter.generatable.d.ts +2 -0
  123. package/dist/entities/base-item-resolver.d.ts +21 -0
  124. package/dist/entities/base-item-resolver.js +9 -0
  125. package/dist/entities/slug.d.ts +5 -0
  126. package/dist/entities/slug.js +6 -0
  127. package/dist/feat/feat.codec.d.ts +9 -0
  128. package/dist/feat/feat.codec.js +10 -0
  129. package/dist/feat/feat.entity-type.d.ts +2 -0
  130. package/dist/feat/feat.parser.d.ts +3 -0
  131. package/dist/feat/feat.parser.js +9 -0
  132. package/dist/feat/feat.schema.d.ts +194 -0
  133. package/dist/feat/feat.schema.js +8 -0
  134. package/dist/feat/feat.types.d.ts +42 -0
  135. package/dist/feat/feat.types.js +0 -0
  136. package/dist/index.d.ts +12 -0
  137. package/dist/index.js +139149 -0
  138. package/dist/inline-tag-parser.d.ts +11 -0
  139. package/dist/inline-tag-parser.js +6 -0
  140. package/dist/item/item.actions-map.d.ts +41 -0
  141. package/dist/item/item.actions-map.js +85 -0
  142. package/dist/item/item.ai-schema.d.ts +35 -0
  143. package/dist/item/item.ai-schema.js +6 -0
  144. package/dist/item/item.attunement.d.ts +18 -0
  145. package/dist/item/item.attunement.js +12 -0
  146. package/dist/item/item.bonuses.d.ts +2 -0
  147. package/dist/item/item.bonuses.js +7 -0
  148. package/dist/item/item.codec.d.ts +3 -0
  149. package/dist/item/item.codec.js +8 -0
  150. package/dist/item/item.conditions.d.ts +10 -0
  151. package/dist/item/item.conditions.js +8 -0
  152. package/dist/item/item.conditions.types.d.ts +28 -0
  153. package/dist/item/item.conditions.types.js +0 -0
  154. package/dist/item/item.enrichment.d.ts +4 -0
  155. package/dist/item/item.enrichment.js +9 -0
  156. package/dist/item/item.entity-type.d.ts +2 -0
  157. package/dist/item/item.generatable.d.ts +2 -0
  158. package/dist/item/item.parser.d.ts +3 -0
  159. package/dist/item/item.parser.js +7 -0
  160. package/dist/item/item.schema.d.ts +174 -0
  161. package/dist/item/item.schema.js +8 -0
  162. package/dist/item/item.types.d.ts +108 -0
  163. package/dist/item/item.types.js +0 -0
  164. package/dist/monster/monster.ai-schema.d.ts +67 -0
  165. package/dist/monster/monster.ai-schema.js +6 -0
  166. package/dist/monster/monster.codec.d.ts +13 -0
  167. package/dist/monster/monster.enrichment.d.ts +10 -0
  168. package/dist/monster/monster.enrichment.js +19 -0
  169. package/dist/monster/monster.entity-type.d.ts +2 -0
  170. package/dist/monster/monster.generatable.d.ts +2 -0
  171. package/dist/monster/monster.parser.d.ts +3 -0
  172. package/dist/monster/monster.parser.js +6 -0
  173. package/dist/monster/monster.resolve.d.ts +10 -0
  174. package/dist/monster/monster.types.d.ts +29 -0
  175. package/dist/monster/monster.types.js +1 -0
  176. package/dist/npc/npc.ai-schema.d.ts +6 -0
  177. package/dist/npc/npc.entity-type.d.ts +2 -0
  178. package/dist/npc/npc.generatable.d.ts +2 -0
  179. package/dist/optional-feature/optional-feature.codec.d.ts +14 -0
  180. package/dist/optional-feature/optional-feature.codec.js +11 -0
  181. package/dist/optional-feature/optional-feature.entity-type.d.ts +2 -0
  182. package/dist/optional-feature/optional-feature.parser.d.ts +3 -0
  183. package/dist/optional-feature/optional-feature.parser.js +10 -0
  184. package/dist/optional-feature/optional-feature.schema.d.ts +236 -0
  185. package/dist/optional-feature/optional-feature.schema.js +9 -0
  186. package/dist/pack.d.ts +11 -0
  187. package/dist/pc/conditions.constants.d.ts +3 -0
  188. package/dist/pc/conditions.constants.js +8 -0
  189. package/dist/pc/decision-recognizer.d.ts +4 -0
  190. package/dist/pc/decision-recognizer.js +8 -0
  191. package/dist/pc/pc.conditions.d.ts +3 -0
  192. package/dist/pc/pc.conditions.js +6 -0
  193. package/dist/pc/pc.decision-engine.d.ts +97 -0
  194. package/dist/pc/pc.decision-engine.js +19 -0
  195. package/dist/pc/pc.equipment.d.ts +12 -0
  196. package/dist/pc/pc.equipment.js +15 -0
  197. package/dist/pc/pc.feature-effects.d.ts +95 -0
  198. package/dist/pc/pc.feature-effects.js +9 -0
  199. package/dist/pc/pc.formula-context.d.ts +4 -0
  200. package/dist/pc/pc.formula-context.js +11 -0
  201. package/dist/pc/pc.parser.d.ts +3 -0
  202. package/dist/pc/pc.parser.js +41 -0
  203. package/dist/pc/pc.pools.d.ts +12 -0
  204. package/dist/pc/pc.pools.js +15 -0
  205. package/dist/pc/pc.proficiencies.d.ts +8 -0
  206. package/dist/pc/pc.proficiencies.js +47 -0
  207. package/dist/pc/pc.proficiency-query.d.ts +11 -0
  208. package/dist/pc/pc.proficiency-query.js +17 -0
  209. package/dist/pc/pc.recalc.d.ts +105 -0
  210. package/dist/pc/pc.recalc.js +662 -0
  211. package/dist/pc/pc.resolver.d.ts +34 -0
  212. package/dist/pc/pc.resolver.js +267 -0
  213. package/dist/pc/pc.resource-seed.d.ts +10 -0
  214. package/dist/pc/pc.resource-seed.js +40 -0
  215. package/dist/pc/pc.rest.d.ts +23 -0
  216. package/dist/pc/pc.rest.js +128 -0
  217. package/dist/pc/pc.schema.d.ts +294 -0
  218. package/dist/pc/pc.schema.js +7 -0
  219. package/dist/pc/pc.slotting.d.ts +22 -0
  220. package/dist/pc/pc.slotting.js +20 -0
  221. package/dist/pc/pc.spellcasting.d.ts +56 -0
  222. package/dist/pc/pc.spellcasting.js +16 -0
  223. package/dist/pc/pc.table-column.d.ts +12 -0
  224. package/dist/pc/pc.table-column.js +8 -0
  225. package/dist/pc/pc.types.d.ts +514 -0
  226. package/dist/pc/pc.types.js +0 -0
  227. package/dist/race/race.codec.d.ts +9 -0
  228. package/dist/race/race.codec.js +13 -0
  229. package/dist/race/race.entity-type.d.ts +2 -0
  230. package/dist/race/race.parser.d.ts +3 -0
  231. package/dist/race/race.parser.js +12 -0
  232. package/dist/race/race.schema.d.ts +67 -0
  233. package/dist/race/race.schema.js +11 -0
  234. package/dist/race/race.types.d.ts +44 -0
  235. package/dist/race/race.types.js +0 -0
  236. package/dist/schemas/attack-schema.d.ts +38 -0
  237. package/dist/schemas/choice-schema.d.ts +5 -0
  238. package/dist/schemas/choice-schema.js +7 -0
  239. package/dist/schemas/duration-schema.d.ts +13 -0
  240. package/dist/schemas/duration-schema.js +6 -0
  241. package/dist/schemas/equipment-grant-schema.d.ts +6 -0
  242. package/dist/schemas/equipment-grant-schema.js +12 -0
  243. package/dist/schemas/feature-effect-schema.d.ts +131 -0
  244. package/dist/schemas/feature-effect-schema.js +6 -0
  245. package/dist/schemas/feature-schema.d.ts +2 -0
  246. package/dist/schemas/feature-schema.js +10 -0
  247. package/dist/schemas/index.d.ts +6 -0
  248. package/dist/schemas/resource-schema.d.ts +95 -0
  249. package/dist/schemas/resource-schema.js +12 -0
  250. package/dist/schemas/selection-pool-schema.d.ts +34 -0
  251. package/dist/schemas/selection-pool-schema.js +10 -0
  252. package/dist/spell/spell.access.d.ts +15 -0
  253. package/dist/spell/spell.access.js +25 -0
  254. package/dist/spell/spell.ai-schema.d.ts +24 -0
  255. package/dist/spell/spell.ai-schema.js +6 -0
  256. package/dist/spell/spell.codec.d.ts +3 -0
  257. package/dist/spell/spell.codec.js +8 -0
  258. package/dist/spell/spell.enrichment.d.ts +2 -0
  259. package/dist/spell/spell.enrichment.js +9 -0
  260. package/dist/spell/spell.entity-type.d.ts +2 -0
  261. package/dist/spell/spell.filter.d.ts +15 -0
  262. package/dist/spell/spell.filter.js +87 -0
  263. package/dist/spell/spell.generatable.d.ts +2 -0
  264. package/dist/spell/spell.parser.d.ts +3 -0
  265. package/dist/spell/spell.parser.js +7 -0
  266. package/dist/spell/spell.scaling.d.ts +14 -0
  267. package/dist/spell/spell.scaling.js +28 -0
  268. package/dist/spell/spell.schema.d.ts +31 -0
  269. package/dist/spell/spell.schema.js +6 -0
  270. package/dist/spell/spell.types.d.ts +25 -0
  271. package/dist/spell/spell.types.js +0 -0
  272. package/dist/srd-store.d.ts +53 -0
  273. package/dist/subclass/subclass.codec.d.ts +11 -0
  274. package/dist/subclass/subclass.codec.js +14 -0
  275. package/dist/subclass/subclass.entity-type.d.ts +2 -0
  276. package/dist/subclass/subclass.parser.d.ts +3 -0
  277. package/dist/subclass/subclass.parser.js +13 -0
  278. package/dist/subclass/subclass.schema.d.ts +118 -0
  279. package/dist/subclass/subclass.schema.js +12 -0
  280. package/dist/subclass/subclass.types.d.ts +20 -0
  281. package/dist/subclass/subclass.types.js +0 -0
  282. package/dist/types/abilities.d.ts +8 -0
  283. package/dist/types/abilities.js +0 -0
  284. package/dist/types/ac.d.ts +5 -0
  285. package/dist/types/attack.d.ts +22 -0
  286. package/dist/types/attack.js +0 -0
  287. package/dist/types/casting-option.d.ts +14 -0
  288. package/dist/types/casting-option.js +0 -0
  289. package/dist/types/choice.d.ts +66 -0
  290. package/dist/types/choice.js +6 -0
  291. package/dist/types/edition.d.ts +4 -0
  292. package/dist/types/edition.js +0 -0
  293. package/dist/types/equipment-grant.d.ts +41 -0
  294. package/dist/types/equipment-grant.js +0 -0
  295. package/dist/types/feature-effect.d.ts +79 -0
  296. package/dist/types/feature-effect.js +0 -0
  297. package/dist/types/feature.d.ts +41 -0
  298. package/dist/types/feature.js +0 -0
  299. package/dist/types/formula-context.d.ts +7 -0
  300. package/dist/types/formula-context.js +0 -0
  301. package/dist/types/hp.d.ts +4 -0
  302. package/dist/types/index.d.ts +10 -0
  303. package/dist/types/item-conditions.types.d.ts +63 -0
  304. package/dist/types/item-conditions.types.js +0 -0
  305. package/dist/types/optional-feature.types.d.ts +60 -0
  306. package/dist/types/optional-feature.types.js +0 -0
  307. package/dist/types/resource.d.ts +44 -0
  308. package/dist/types/resource.js +0 -0
  309. package/dist/types/selection-pool.d.ts +37 -0
  310. package/dist/types/selection-pool.js +0 -0
  311. package/dist/types/speed.d.ts +8 -0
  312. package/dist/weapon/weapon.codec.d.ts +12 -0
  313. package/dist/weapon/weapon.codec.js +8 -0
  314. package/dist/weapon/weapon.entity-type.d.ts +2 -0
  315. package/dist/weapon/weapon.parser.d.ts +3 -0
  316. package/dist/weapon/weapon.parser.js +7 -0
  317. package/dist/weapon/weapon.schema.d.ts +34 -0
  318. package/dist/weapon/weapon.schema.js +6 -0
  319. package/dist/weapon/weapon.types.d.ts +36 -0
  320. package/dist/weapon/weapon.types.js +0 -0
  321. package/package.json +32 -0
  322. package/src/data-srd/ATTRIBUTION.md +2 -0
@@ -0,0 +1,19 @@
1
+ import {
2
+ __matchesFilterForTest,
3
+ bareEntitySlug,
4
+ buildDecisionLedger,
5
+ collectChosenAbilityPoints,
6
+ collectChosenProficiencies,
7
+ wikilinkTailSlug
8
+ } from "../chunk-TJCNX6UZ.js";
9
+ import "../chunk-BH6AMZVY.js";
10
+ import "../chunk-JEYQU3JT.js";
11
+ import "../chunk-WP2CX2JO.js";
12
+ export {
13
+ __matchesFilterForTest,
14
+ bareEntitySlug,
15
+ buildDecisionLedger,
16
+ collectChosenAbilityPoints,
17
+ collectChosenProficiencies,
18
+ wikilinkTailSlug
19
+ };
@@ -0,0 +1,12 @@
1
+ import type { EntityRegistry } from "@archivist-gg/core";
2
+ import type { Ability } from "@archivist-gg/dnd5e";
3
+ import type { AppliedBonuses, DerivedEquipment, ResolvedCharacter, ProficiencySet } from "./pc.types.js";
4
+ interface ProficienciesForQuery {
5
+ armor: ProficiencySet;
6
+ weapons: ProficiencySet;
7
+ tools: ProficiencySet;
8
+ }
9
+ export declare function emptyAppliedBonuses(): AppliedBonuses;
10
+ export declare function computeAppliedBonuses(resolved: ResolvedCharacter, _profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[]): AppliedBonuses;
11
+ export declare function computeSlotsAndAttacks(resolved: ResolvedCharacter, mods: Record<Ability, number>, profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[], proficiencyBonus: number, weaponAbilityOverride?: Ability): DerivedEquipment;
12
+ export {};
@@ -0,0 +1,15 @@
1
+ import {
2
+ computeAppliedBonuses,
3
+ computeSlotsAndAttacks,
4
+ emptyAppliedBonuses
5
+ } from "../chunk-QQ5W2AZP.js";
6
+ import "../chunk-UC4FE5X3.js";
7
+ import "../chunk-LWFTHJIE.js";
8
+ import "../chunk-DNAJRMNN.js";
9
+ import "../chunk-DC74TZNA.js";
10
+ import "../chunk-3TRGRSCH.js";
11
+ export {
12
+ computeAppliedBonuses,
13
+ computeSlotsAndAttacks,
14
+ emptyAppliedBonuses
15
+ };
@@ -0,0 +1,95 @@
1
+ import type { SenseType } from "@archivist-gg/dnd5e/types/feature-effect";
2
+ import type { Ability } from "@archivist-gg/dnd5e";
3
+ import type { ResolvedFeature, RollModifierEntry } from "./pc.types.js";
4
+ /**
5
+ * Aggregated passive feature effects (effects-application engine).
6
+ * One pure scan over resolved.features[].feature.effects[]. Merge semantics
7
+ * mirror pc.conditions mergePartial: numbers add, each sense range takes max,
8
+ * lists union case-insensitively. apply-condition and damage-bonus are action/attack
9
+ * time and intentionally not aggregated; `while`-gated immune-condition
10
+ * entries are skipped entirely (conditional effects are a named deferral).
11
+ */
12
+ export interface FeatureEffectTotals {
13
+ initiative_bonus: number;
14
+ hp_per_level_bonus: number;
15
+ speed_walk_bonus: number;
16
+ /**
17
+ * Absolute walk-speed FLOOR from `speed-bonus` effects with `set:true` (e.g.
18
+ * a "base speed becomes 60" feature). Max across all set effects; 0 = none.
19
+ * recalc applies it as Math.max(set, race + additive bonuses) so it never
20
+ * lowers an already-higher speed and is independent of the additive bonus.
21
+ */
22
+ speed_walk_set: number;
23
+ /** Max range per sense type granted by effects; 0 = none for that type. */
24
+ senses: Record<SenseType, number>;
25
+ /** One term per ac-bonus effect, labeled with the owning feature's name. */
26
+ ac_terms: {
27
+ value: number;
28
+ requires_armor: boolean;
29
+ label: string;
30
+ }[];
31
+ resistances: string[];
32
+ condition_immunities: string[];
33
+ /**
34
+ * skills are kebab-case lowercase slugs (matching skill slugs). armor/weapons
35
+ * are lowercase CATEGORY words ("heavy"/"shield", "simple"/"martial") — the
36
+ * same form class/race/feat grants use; recalc folds them into the matcher's
37
+ * `.categories` bucket, NOT `.specific` (which is per-item slugs). tools/languages
38
+ * keep their display spelling; saves are canonical ability keys.
39
+ */
40
+ proficiencies: {
41
+ skills: string[];
42
+ tools: string[];
43
+ languages: string[];
44
+ saves: Ability[];
45
+ armor: string[];
46
+ weapons: string[];
47
+ };
48
+ /**
49
+ * v1 global melee-attack ability override (Hexblade "Lies", etc.). The first
50
+ * `weapon-ability` effect with a concrete ability (not `"spellcasting"`) wins;
51
+ * `"spellcasting"` is resolved against the caster ability in recalc. `weapons`
52
+ * scope is parsed but ignored here (global override). null = no override.
53
+ */
54
+ weaponAbility: Ability | null;
55
+ /**
56
+ * Order-preserving list of structured advantage/disadvantage entries from
57
+ * `roll-modifier` effects. Pass-through (no dedupe/merge); each entry is
58
+ * labeled with the owning feature's name.
59
+ */
60
+ rollModifiers: RollModifierEntry[];
61
+ /**
62
+ * Lowest weapon-attack crit threshold (natural roll that scores a critical
63
+ * hit) granted by `crit-range` effects. Folds via Math.min from init 20, so
64
+ * 20 = no expansion. spell-only (`applies_to:"spell"`) entries do NOT lower
65
+ * it. recalc maps this onto each AttackRow as `critRange` only when < 20.
66
+ */
67
+ critRange: number;
68
+ /**
69
+ * Max extra attacks per Attack action granted by `extra-attack` effects.
70
+ * Non-stacking (D&D Extra Attack features don't stack): folds via Math.max
71
+ * from init 0, so 0 = no extra attacks. recalc maps this onto
72
+ * DerivedStats.attacksPerAction as `1 + extraAttack`.
73
+ */
74
+ extraAttack: number;
75
+ /**
76
+ * Order-preserving display-only captions surfaced from `reroll-damage` and
77
+ * `attack-rule` effects (e.g. "Reroll 2s", "No disadvantage firing in melee").
78
+ * recalc post-applies this list onto each AttackRow as `attackNotes` only when
79
+ * non-empty, so untouched attack rows keep `attackNotes: undefined`.
80
+ */
81
+ attackNotes: string[];
82
+ }
83
+ export declare function emptyFeatureEffectTotals(): FeatureEffectTotals;
84
+ /**
85
+ * Optional fold inputs. `activeBuffs` is the set of currently-toggled buff
86
+ * ids/slugs (from Character.state.active_buffs + selected pool boons). An
87
+ * `activatable` feature's effects fold ONLY while its id is in this set; a buff
88
+ * is OFF by default, so callers passing no opts see activatable features fold to
89
+ * nothing (correct — a buff is off until toggled). Non-activatable features fold
90
+ * unconditionally regardless of opts.
91
+ */
92
+ export interface FeatureEffectsOpts {
93
+ activeBuffs?: Set<string>;
94
+ }
95
+ export declare function computeFeatureEffects(features: ResolvedFeature[], opts?: FeatureEffectsOpts): FeatureEffectTotals;
@@ -0,0 +1,9 @@
1
+ import {
2
+ computeFeatureEffects,
3
+ emptyFeatureEffectTotals
4
+ } from "../chunk-XURS6Q6Q.js";
5
+ import "../chunk-WP2CX2JO.js";
6
+ export {
7
+ computeFeatureEffects,
8
+ emptyFeatureEffectTotals
9
+ };
@@ -0,0 +1,4 @@
1
+ import type { EntityRegistry } from "@archivist-gg/core";
2
+ import type { FormulaContext } from "@archivist-gg/dnd5e/types/formula-context";
3
+ import type { DerivedStats, ResolvedCharacter } from "./pc.types.js";
4
+ export declare function buildFormulaContext(resolved: ResolvedCharacter, derived: DerivedStats, registry: EntityRegistry): FormulaContext;
@@ -0,0 +1,11 @@
1
+ // src/pc/pc.formula-context.ts
2
+ function buildFormulaContext(resolved, derived, registry) {
3
+ return {
4
+ abilities: resolved.definition.abilities,
5
+ proficiencyBonus: derived.proficiencyBonus,
6
+ compendium: registry
7
+ };
8
+ }
9
+ export {
10
+ buildFormulaContext
11
+ };
@@ -0,0 +1,3 @@
1
+ import type { ParseResult } from "@archivist-gg/core";
2
+ import type { Character } from "./pc.types.js";
3
+ export declare function parsePC(source: string): ParseResult<Character>;
@@ -0,0 +1,41 @@
1
+ import {
2
+ characterSchema
3
+ } from "../chunk-ZLG6FQFB.js";
4
+ import "../chunk-TZK36BU7.js";
5
+
6
+ // src/pc/pc.parser.ts
7
+ import * as yaml from "js-yaml";
8
+ function parsePC(source) {
9
+ let raw;
10
+ try {
11
+ raw = yaml.load(source);
12
+ } catch (e) {
13
+ const msg = e instanceof Error ? e.message : String(e);
14
+ return { success: false, error: `YAML parse error: ${msg}` };
15
+ }
16
+ if (!raw || typeof raw !== "object") {
17
+ return { success: false, error: "Invalid YAML: expected an object" };
18
+ }
19
+ const result = characterSchema.safeParse(raw);
20
+ if (!result.success) {
21
+ const issue = result.error.issues[0];
22
+ const path = issue.path.length ? issue.path.join(".") : "(root)";
23
+ return { success: false, error: `${path}: ${issue.message}` };
24
+ }
25
+ const data = result.data;
26
+ const legacyState = data.state;
27
+ const legacyCurrency = legacyState.currency;
28
+ if (legacyCurrency && !data.currency) {
29
+ data.currency = legacyCurrency;
30
+ }
31
+ if (legacyCurrency) {
32
+ delete legacyState.currency;
33
+ }
34
+ if (legacyState.attuned_items) {
35
+ delete legacyState.attuned_items;
36
+ }
37
+ return { success: true, data };
38
+ }
39
+ export {
40
+ parsePC
41
+ };
@@ -0,0 +1,12 @@
1
+ import type { RegisteredEntity } from "@archivist-gg/core";
2
+ import type { ResolvedCharacter, ResolvedClass, ResolvedPool } from "./pc.types.js";
3
+ import type { SelectionPool } from "@archivist-gg/dnd5e/types/selection-pool";
4
+ import type { OptionalFeatureEntity } from "@archivist-gg/dnd5e/types/optional-feature.types";
5
+ /** Structural subset of EntityRegistry used here (lets tests pass a fake). */
6
+ export interface PoolRegistry {
7
+ search(query: string, entityType: string, limit: number): RegisteredEntity[];
8
+ getByTypeAndSlug(entityType: string, slug: string): RegisteredEntity | undefined;
9
+ }
10
+ export declare function levelPrereqMax(d: OptionalFeatureEntity): number;
11
+ export declare function resolvePool(rc: ResolvedClass, classIndex: number, pool: SelectionPool, registry: PoolRegistry): ResolvedPool;
12
+ export declare function resolveAllPools(resolved: ResolvedCharacter, registry: PoolRegistry): ResolvedPool[];
@@ -0,0 +1,15 @@
1
+ import {
2
+ levelPrereqMax,
3
+ resolveAllPools,
4
+ resolvePool
5
+ } from "../chunk-6PXE7T7C.js";
6
+ import "../chunk-5XUXXAQJ.js";
7
+ import "../chunk-TJCNX6UZ.js";
8
+ import "../chunk-BH6AMZVY.js";
9
+ import "../chunk-JEYQU3JT.js";
10
+ import "../chunk-WP2CX2JO.js";
11
+ export {
12
+ levelPrereqMax,
13
+ resolveAllPools,
14
+ resolvePool
15
+ };
@@ -0,0 +1,8 @@
1
+ import type { ResolvedCharacter } from "./pc.types.js";
2
+ export interface ProficiencyAggregate {
3
+ armor: string[];
4
+ weapons: string[];
5
+ tools: string[];
6
+ languages: string[];
7
+ }
8
+ export declare function aggregateProficiencies(resolved: ResolvedCharacter): ProficiencyAggregate;
@@ -0,0 +1,47 @@
1
+ // src/pc/pc.proficiencies.ts
2
+ function aggregateProficiencies(resolved) {
3
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
4
+ const armor = /* @__PURE__ */ new Set();
5
+ const weapons = /* @__PURE__ */ new Set();
6
+ const tools = /* @__PURE__ */ new Set();
7
+ const languages = /* @__PURE__ */ new Set();
8
+ for (const c of resolved.classes) {
9
+ const prof = (_a = c.entity) == null ? void 0 : _a.proficiencies;
10
+ if (!prof) continue;
11
+ for (const a of (_b = prof.armor) != null ? _b : []) armor.add(prettyName(a));
12
+ if ((_c = prof.weapons) == null ? void 0 : _c.fixed) for (const w of prof.weapons.fixed) weapons.add(prettyName(w));
13
+ if ((_d = prof.weapons) == null ? void 0 : _d.categories) for (const w of prof.weapons.categories) weapons.add(prettyName(w));
14
+ if ((_e = prof.tools) == null ? void 0 : _e.fixed) for (const t of prof.tools.fixed) tools.add(prettyName(t));
15
+ }
16
+ const raceLangs = (_f = resolved.race) == null ? void 0 : _f.languages;
17
+ if (raceLangs == null ? void 0 : raceLangs.fixed) for (const l of raceLangs.fixed) languages.add(prettyName(l));
18
+ const bg = resolved.background;
19
+ if (bg) {
20
+ for (const entry of (_g = bg.tool_proficiencies) != null ? _g : []) {
21
+ if (entry.kind === "fixed") for (const t of entry.items) tools.add(prettyName(t));
22
+ }
23
+ for (const entry of (_h = bg.language_proficiencies) != null ? _h : []) {
24
+ if (entry.kind === "fixed") for (const l of entry.languages) languages.add(prettyName(l));
25
+ }
26
+ }
27
+ for (const f of resolved.feats) {
28
+ const grants = f.proficiencies;
29
+ if (!grants) continue;
30
+ for (const a of (_i = grants.armor) != null ? _i : []) armor.add(prettyName(a));
31
+ for (const w of (_j = grants.weapons) != null ? _j : []) weapons.add(prettyName(w));
32
+ for (const t of (_k = grants.tools) != null ? _k : []) tools.add(prettyName(t));
33
+ for (const l of (_l = grants.languages) != null ? _l : []) languages.add(prettyName(l));
34
+ }
35
+ return {
36
+ armor: [...armor].sort(),
37
+ weapons: [...weapons].sort(),
38
+ tools: [...tools].sort(),
39
+ languages: [...languages].sort()
40
+ };
41
+ }
42
+ function prettyName(slug) {
43
+ return slug.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
44
+ }
45
+ export {
46
+ aggregateProficiencies
47
+ };
@@ -0,0 +1,11 @@
1
+ import type { ArmorEntity } from "@archivist-gg/dnd5e/armor/armor.types";
2
+ import type { WeaponEntity } from "@archivist-gg/dnd5e/weapon/weapon.types";
3
+ import type { ProficiencySet } from "./pc.types.js";
4
+ interface ProficienciesForQuery {
5
+ armor: ProficiencySet;
6
+ weapons: ProficiencySet;
7
+ tools: ProficiencySet;
8
+ }
9
+ export declare function isProficientWithWeapon(weapon: WeaponEntity, profs: ProficienciesForQuery): boolean;
10
+ export declare function isProficientWithArmor(armor: ArmorEntity, profs: ProficienciesForQuery): boolean;
11
+ export {};
@@ -0,0 +1,17 @@
1
+ // src/pc/pc.proficiency-query.ts
2
+ function isProficientWithWeapon(weapon, profs) {
3
+ if (profs.weapons.specific.includes(weapon.slug)) return true;
4
+ const baseCategory = weapon.category.split("-")[0];
5
+ return profs.weapons.categories.includes(baseCategory);
6
+ }
7
+ function isProficientWithArmor(armor, profs) {
8
+ if (profs.armor.specific.includes(armor.slug)) return true;
9
+ if (profs.armor.categories.includes(armor.category)) return true;
10
+ if (armor.category === "light" && (profs.armor.categories.includes("medium") || profs.armor.categories.includes("heavy"))) return true;
11
+ if (armor.category === "medium" && profs.armor.categories.includes("heavy")) return true;
12
+ return false;
13
+ }
14
+ export {
15
+ isProficientWithArmor,
16
+ isProficientWithWeapon
17
+ };
@@ -0,0 +1,105 @@
1
+ import type { Ability } from "@archivist-gg/dnd5e";
2
+ import type { FeatEntity } from "@archivist-gg/dnd5e/feat/feat.types";
3
+ import type { RaceEntity } from "@archivist-gg/dnd5e/race/race.types";
4
+ import type { EntityRegistry } from "@archivist-gg/core";
5
+ import type { ACTerm, DerivedStats, ProficiencySet, ResolvedCharacter, ResolvedClass, CharacterOverrides } from "./pc.types.js";
6
+ /**
7
+ * PHB "fixed average" value per hit die (per level beyond first). Called
8
+ * "average" in the PHB but actually ceil((die + 1) / 2); equivalent to
9
+ * Math.floor(die / 2) + 1 for even dice.
10
+ *
11
+ * d6 → 4, d8 → 5, d10 → 6, d12 → 7.
12
+ */
13
+ export declare function phbAverageForDie(hitDieStr: string): number;
14
+ /** Extracts the integer size from "d8" / "d10" / 8 / 10. */
15
+ export declare function parseDieSize(die: string | number | undefined | null): number | null;
16
+ /**
17
+ * Flattens RaceEntity.ability_score_increases into a partial ability→bonus map.
18
+ * Fixed increases contribute their amount directly. Choice increases are ignored
19
+ * here — they're expected to come through class.choices with a specific ability
20
+ * selected, which computeAbilityScores handles separately.
21
+ */
22
+ export declare function flattenRaceAsi(race: RaceEntity | null): Partial<Record<Ability, number>>;
23
+ /**
24
+ * Sums the LEGACY class-level ASI-BRANCH allocations (`choices[lvl].asi`) per
25
+ * ability across every class. This is the path taken when an L4/L8-style
26
+ * "Ability Score Increase or Feat" decision resolves to the plain +2 ASI branch
27
+ * rather than a feat. Shared by both `computeAbilityScores`' fold and
28
+ * `abilityBonusBreakdown`'s `class` bucket so the two reads can never drift.
29
+ *
30
+ * Disjoint from chosen-feat ability-points (`choices[lvl]["feat:<id>"]`) and from
31
+ * origin ability-points — no source double-counts.
32
+ */
33
+ export declare function collectClassAsiBranch(resolved: ResolvedCharacter): Partial<Record<Ability, number>>;
34
+ /** Per-ability bonus provenance for the builder's obelisk captions:
35
+ * species = fixed race ASI + subrace fixed ASI + race ability-points choices;
36
+ * background = background ability-points choices;
37
+ * class = legacy class ASI-BRANCH allocations (the L4 asi-or-feat → asi path);
38
+ * feat = class chosen-feat ability-points (the L4 asi-or-feat → feat path) +
39
+ * flat feat ability_bonuses (e.g. Athlete +1 STR). All already fold into
40
+ * computeAbilityScores totals, so the caption must account for them or a
41
+ * tile reads higher than the named sources explain (smoke r1/r5c). */
42
+ export declare function abilityBonusBreakdown(resolved: ResolvedCharacter): Record<Ability, {
43
+ species: number;
44
+ background: number;
45
+ class: number;
46
+ feat: number;
47
+ }>;
48
+ /**
49
+ * PC-oriented multiclass HP.
50
+ * - First class's first level: max(hit_die) + conMod.
51
+ * - Every subsequent level (in any class): phbAverageForDie(thatLevel'sClass) + conMod.
52
+ * CON mod contributes once per total level.
53
+ */
54
+ export declare function multiclassMaxHP(classes: ResolvedClass[], conMod: number): number;
55
+ /**
56
+ * Default AC = 10 + DEX mod. If any class's features include an
57
+ * "Unarmored Defense"–style feature with a structured flag, applies the
58
+ * variant (Monk: +WIS; Barbarian: +CON). Falls back to feature-name
59
+ * regex matching with a warning pushed onto `warnings`.
60
+ */
61
+ export declare function unarmoredAC(resolved: ResolvedCharacter, mods: Record<Ability, number>, warnings: string[]): number;
62
+ /**
63
+ * Same logic as `unarmoredAC` but also returns a structured breakdown of the
64
+ * contributing terms (Base 10, DEX, optional class unarmored defense ability).
65
+ * Used by recalc to assemble a richer acBreakdown when no armor is equipped.
66
+ */
67
+ export declare function unarmoredACBreakdown(resolved: ResolvedCharacter, mods: Record<Ability, number>, warnings: string[]): {
68
+ total: number;
69
+ terms: ACTerm[];
70
+ };
71
+ /** Initiative = DEX mod + Alert (+5 in 2014). Extendable via feat flags. */
72
+ export declare function initiativeBonus(dexMod: number, feats: FeatEntity[], edition: "2014" | "2024"): number;
73
+ /** Speed = race.speed.walk + flat bonuses from feats (e.g., Mobile +10). */
74
+ export declare function speedFromRace(resolved: ResolvedCharacter): number;
75
+ /**
76
+ * Folds class-level CHOSEN-FEAT ability-points into per-ability totals.
77
+ *
78
+ * When the L4-style "asi or feat" decision resolves to a feat that carries
79
+ * `ability-points` choices (e.g. Ability Score Improvement, the epic Boons),
80
+ * the picker persists the allocation under the namespaced key
81
+ * `choices[lvl]["feat:" + choice.id]` (the engine's `buildItem` surfaces those
82
+ * children; see pc.decision-engine.ts). This is disjoint from both the legacy
83
+ * asi-BRANCH key (`choices[lvl].asi`) and origin ability-points, so no source
84
+ * double-counts. The chosen feat entity is resolved from `resolved.feats`
85
+ * (already looked up by the resolver) — no registry needed here.
86
+ *
87
+ * Clamps defensively (per-ability max_per, then stops at the points total in
88
+ * ABILITY_KEYS order), mirroring collectChosenAbilityPoints.
89
+ */
90
+ export declare function collectClassFeatAbilityPoints(resolved: ResolvedCharacter): Partial<Record<Ability, number>>;
91
+ /**
92
+ * Combines racial ASI (from race.ability_score_increases), feat ASI,
93
+ * class-choice ASI (from classes[i].choices[lvl].asi), chosen-feat ASI
94
+ * (from classes[i].choices[lvl]["feat:<id>"]), and user overrides.
95
+ * Overrides win; ASI sources sum unconditionally.
96
+ */
97
+ export declare function computeAbilityScores(resolved: ResolvedCharacter, overrides: CharacterOverrides): Record<Ability, number>;
98
+ export declare function computeProficiencies(resolved: ResolvedCharacter): {
99
+ armor: ProficiencySet;
100
+ weapons: ProficiencySet;
101
+ tools: ProficiencySet;
102
+ languages: string[];
103
+ saves: Ability[];
104
+ };
105
+ export declare function recalc(resolved: ResolvedCharacter, registry?: EntityRegistry): DerivedStats;