@archivist-gg/dnd5e 0.3.7 → 0.3.8

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 (65) hide show
  1. package/dist/background/background.codec.js +5 -5
  2. package/dist/background/background.parser.js +4 -4
  3. package/dist/background/background.schema.js +3 -3
  4. package/dist/{chunk-3PZHBLFG.js → chunk-2Q374PZ3.js} +1 -1
  5. package/dist/{chunk-BJFL4KYG.js → chunk-47SCRXGM.js} +3 -3
  6. package/dist/{chunk-MYW7AOUE.js → chunk-5QM7YNGV.js} +1 -1
  7. package/dist/{chunk-ABQ6ZWAF.js → chunk-5SMMRAO2.js} +1 -1
  8. package/dist/{chunk-7MRW4RTH.js → chunk-5VTDYZIW.js} +1 -1
  9. package/dist/{chunk-BS355LND.js → chunk-DIAYWWHG.js} +1 -1
  10. package/dist/{chunk-H4VEMVOO.js → chunk-EISRDJUV.js} +1 -1
  11. package/dist/{chunk-7WNQJAZW.js → chunk-FYM3ROGA.js} +2 -2
  12. package/dist/{chunk-MT4RWROQ.js → chunk-GD2CFJ3T.js} +2 -2
  13. package/dist/{chunk-CQAL67R3.js → chunk-HRG4URUK.js} +1 -1
  14. package/dist/{chunk-A6YL53NC.js → chunk-IVLA24R3.js} +1 -1
  15. package/dist/{chunk-KPEJMNRD.js → chunk-IXMS2HHP.js} +22 -7
  16. package/dist/{chunk-IWRVOCT5.js → chunk-LEHDXPY6.js} +1 -1
  17. package/dist/{chunk-JOVMV2X5.js → chunk-N4JJNGLZ.js} +3 -3
  18. package/dist/{chunk-63XQXPZL.js → chunk-O5WXS3G5.js} +1 -1
  19. package/dist/{chunk-DTCR4DBF.js → chunk-Q6L2RASW.js} +3 -3
  20. package/dist/{chunk-2BI5NAXK.js → chunk-QCKOVD3K.js} +2 -2
  21. package/dist/{chunk-NNAQ4KQF.js → chunk-RW42SHFM.js} +1 -1
  22. package/dist/{chunk-EYZCCWG2.js → chunk-TEKRIRNZ.js} +1 -1
  23. package/dist/{chunk-B4TQTJVC.js → chunk-U3DNWCEI.js} +1 -1
  24. package/dist/{chunk-RWZTGMSN.js → chunk-UYBCC473.js} +1 -1
  25. package/dist/{chunk-ULCQ73LA.js → chunk-VMIFD2RB.js} +1 -1
  26. package/dist/{chunk-X3D6LXUU.js → chunk-VTKJOAJD.js} +1 -0
  27. package/dist/{chunk-3BMVVNCS.js → chunk-WNQ2O2IS.js} +1 -1
  28. package/dist/{chunk-JKLRBILX.js → chunk-YRTI2FLD.js} +1 -1
  29. package/dist/{chunk-UA3I2YSO.js → chunk-ZJXSXVFP.js} +1 -1
  30. package/dist/class/class.codec.js +7 -7
  31. package/dist/class/class.parser.js +6 -6
  32. package/dist/class/class.schema.js +5 -5
  33. package/dist/feat/feat.codec.js +6 -6
  34. package/dist/feat/feat.parser.js +5 -5
  35. package/dist/feat/feat.schema.d.ts +14 -0
  36. package/dist/feat/feat.schema.js +4 -4
  37. package/dist/index.js +24 -24
  38. package/dist/monster/monster.parser.js +6 -6
  39. package/dist/monster/monster.schema.js +5 -5
  40. package/dist/optional-feature/optional-feature.codec.js +5 -5
  41. package/dist/optional-feature/optional-feature.parser.js +4 -4
  42. package/dist/optional-feature/optional-feature.schema.d.ts +15 -0
  43. package/dist/optional-feature/optional-feature.schema.js +3 -3
  44. package/dist/pc/pc.decision-engine.js +2 -2
  45. package/dist/pc/pc.feature-effects.d.ts +15 -0
  46. package/dist/pc/pc.feature-effects.js +1 -1
  47. package/dist/pc/pc.proficiencies.js +2 -2
  48. package/dist/pc/pc.recalc.js +45 -15
  49. package/dist/pc/pc.resolver.js +2 -2
  50. package/dist/pc/pc.types.d.ts +19 -0
  51. package/dist/race/race.codec.js +7 -7
  52. package/dist/race/race.parser.js +6 -6
  53. package/dist/race/race.schema.js +5 -5
  54. package/dist/schemas/choice-schema.js +2 -2
  55. package/dist/schemas/feature-effect-schema.d.ts +14 -0
  56. package/dist/schemas/feature-effect-schema.js +1 -1
  57. package/dist/schemas/feature-schema.js +4 -4
  58. package/dist/schemas/resource-schema.d.ts +1 -0
  59. package/dist/schemas/resource-schema.js +1 -1
  60. package/dist/subclass/subclass.codec.js +7 -7
  61. package/dist/subclass/subclass.parser.js +6 -6
  62. package/dist/subclass/subclass.schema.js +5 -5
  63. package/dist/types/feature-effect.d.ts +5 -0
  64. package/dist/types/resource.d.ts +1 -1
  65. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@ import "./chunk-HZA7OE7N.js";
5
5
  import "./chunk-2DFENQIJ.js";
6
6
  import {
7
7
  subclassCodec
8
- } from "./chunk-B4TQTJVC.js";
9
- import "./chunk-ABQ6ZWAF.js";
10
- import "./chunk-MT4RWROQ.js";
8
+ } from "./chunk-U3DNWCEI.js";
9
+ import "./chunk-5SMMRAO2.js";
10
+ import "./chunk-GD2CFJ3T.js";
11
11
  import {
12
12
  spellInputSchema
13
13
  } from "./chunk-656QCX4U.js";
@@ -19,9 +19,9 @@ import {
19
19
  } from "./chunk-WSVMLNTO.js";
20
20
  import {
21
21
  raceCodec
22
- } from "./chunk-CQAL67R3.js";
23
- import "./chunk-7MRW4RTH.js";
24
- import "./chunk-2BI5NAXK.js";
22
+ } from "./chunk-HRG4URUK.js";
23
+ import "./chunk-5VTDYZIW.js";
24
+ import "./chunk-QCKOVD3K.js";
25
25
  import "./chunk-OZP6JFGT.js";
26
26
  import "./chunk-VQAXTIBW.js";
27
27
  import {
@@ -34,14 +34,14 @@ import {
34
34
  } from "./chunk-6PXTNCBP.js";
35
35
  import {
36
36
  parseMonster
37
- } from "./chunk-3BMVVNCS.js";
38
- import "./chunk-A6YL53NC.js";
37
+ } from "./chunk-WNQ2O2IS.js";
38
+ import "./chunk-IVLA24R3.js";
39
39
  import "./chunk-IKSMX4TN.js";
40
40
  import {
41
41
  optionalFeatureCodec
42
- } from "./chunk-MYW7AOUE.js";
43
- import "./chunk-NNAQ4KQF.js";
44
- import "./chunk-7WNQJAZW.js";
42
+ } from "./chunk-5QM7YNGV.js";
43
+ import "./chunk-RW42SHFM.js";
44
+ import "./chunk-FYM3ROGA.js";
45
45
  import {
46
46
  itemCodec
47
47
  } from "./chunk-4XTNPNQB.js";
@@ -64,23 +64,23 @@ import {
64
64
  } from "./chunk-LSLSG67V.js";
65
65
  import {
66
66
  featCodec
67
- } from "./chunk-JKLRBILX.js";
68
- import "./chunk-RWZTGMSN.js";
69
- import "./chunk-BJFL4KYG.js";
67
+ } from "./chunk-YRTI2FLD.js";
68
+ import "./chunk-UYBCC473.js";
69
+ import "./chunk-47SCRXGM.js";
70
70
  import "./chunk-DEEHHLAP.js";
71
71
  import "./chunk-PDJSUH24.js";
72
72
  import "./chunk-WELIKLZF.js";
73
73
  import {
74
74
  classCodec
75
- } from "./chunk-BS355LND.js";
76
- import "./chunk-H4VEMVOO.js";
75
+ } from "./chunk-DIAYWWHG.js";
76
+ import "./chunk-EISRDJUV.js";
77
77
  import "./chunk-4U55VNC7.js";
78
- import "./chunk-DTCR4DBF.js";
78
+ import "./chunk-Q6L2RASW.js";
79
79
  import "./chunk-23LZLBJK.js";
80
80
  import "./chunk-CJYCVNW2.js";
81
- import "./chunk-JOVMV2X5.js";
81
+ import "./chunk-N4JJNGLZ.js";
82
82
  import "./chunk-WYGD2UGN.js";
83
- import "./chunk-UA3I2YSO.js";
83
+ import "./chunk-ZJXSXVFP.js";
84
84
  import {
85
85
  parseCondition
86
86
  } from "./chunk-6X2NV665.js";
@@ -91,12 +91,12 @@ import "./chunk-5N2GW72F.js";
91
91
  import "./chunk-JC5UNIVM.js";
92
92
  import {
93
93
  backgroundCodec
94
- } from "./chunk-ULCQ73LA.js";
95
- import "./chunk-3PZHBLFG.js";
96
- import "./chunk-63XQXPZL.js";
94
+ } from "./chunk-VMIFD2RB.js";
95
+ import "./chunk-2Q374PZ3.js";
96
+ import "./chunk-O5WXS3G5.js";
97
97
  import "./chunk-IN4M4X7P.js";
98
- import "./chunk-IWRVOCT5.js";
99
- import "./chunk-X3D6LXUU.js";
98
+ import "./chunk-LEHDXPY6.js";
99
+ import "./chunk-VTKJOAJD.js";
100
100
  import "./chunk-UA5KS2PL.js";
101
101
 
102
102
  // src/monster/monster.codec.ts
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  migrateLegacy,
3
3
  parseMonster
4
- } from "../chunk-3BMVVNCS.js";
5
- import "../chunk-A6YL53NC.js";
6
- import "../chunk-JOVMV2X5.js";
4
+ } from "../chunk-WNQ2O2IS.js";
5
+ import "../chunk-IVLA24R3.js";
6
+ import "../chunk-N4JJNGLZ.js";
7
7
  import "../chunk-WYGD2UGN.js";
8
- import "../chunk-UA3I2YSO.js";
9
- import "../chunk-IWRVOCT5.js";
10
- import "../chunk-X3D6LXUU.js";
8
+ import "../chunk-ZJXSXVFP.js";
9
+ import "../chunk-LEHDXPY6.js";
10
+ import "../chunk-VTKJOAJD.js";
11
11
  import "../chunk-UA5KS2PL.js";
12
12
  export {
13
13
  migrateLegacy,
@@ -11,12 +11,12 @@ import {
11
11
  monsterSpeedSchema,
12
12
  monsterSpellcastingSchema,
13
13
  monsterTypeSchema
14
- } from "../chunk-A6YL53NC.js";
15
- import "../chunk-JOVMV2X5.js";
14
+ } from "../chunk-IVLA24R3.js";
15
+ import "../chunk-N4JJNGLZ.js";
16
16
  import "../chunk-WYGD2UGN.js";
17
- import "../chunk-UA3I2YSO.js";
18
- import "../chunk-IWRVOCT5.js";
19
- import "../chunk-X3D6LXUU.js";
17
+ import "../chunk-ZJXSXVFP.js";
18
+ import "../chunk-LEHDXPY6.js";
19
+ import "../chunk-VTKJOAJD.js";
20
20
  import "../chunk-UA5KS2PL.js";
21
21
  export {
22
22
  MONSTER_KNOWN_KEYS,
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  optionalFeatureCodec
3
- } from "../chunk-MYW7AOUE.js";
4
- import "../chunk-NNAQ4KQF.js";
5
- import "../chunk-7WNQJAZW.js";
3
+ } from "../chunk-5QM7YNGV.js";
4
+ import "../chunk-RW42SHFM.js";
5
+ import "../chunk-FYM3ROGA.js";
6
6
  import "../chunk-WYGD2UGN.js";
7
- import "../chunk-UA3I2YSO.js";
8
- import "../chunk-X3D6LXUU.js";
7
+ import "../chunk-ZJXSXVFP.js";
8
+ import "../chunk-VTKJOAJD.js";
9
9
  import "../chunk-UA5KS2PL.js";
10
10
  export {
11
11
  optionalFeatureCodec
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  parseOptionalFeature
3
- } from "../chunk-NNAQ4KQF.js";
4
- import "../chunk-7WNQJAZW.js";
3
+ } from "../chunk-RW42SHFM.js";
4
+ import "../chunk-FYM3ROGA.js";
5
5
  import "../chunk-WYGD2UGN.js";
6
- import "../chunk-UA3I2YSO.js";
7
- import "../chunk-X3D6LXUU.js";
6
+ import "../chunk-ZJXSXVFP.js";
7
+ import "../chunk-VTKJOAJD.js";
8
8
  import "../chunk-UA5KS2PL.js";
9
9
  export {
10
10
  parseOptionalFeature
@@ -65,6 +65,20 @@ export declare const optionalFeatureEntitySchema: z.ZodObject<{
65
65
  value: z.ZodNumber;
66
66
  condition: z.ZodOptional<z.ZodString>;
67
67
  subject: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>, z.ZodObject<{
69
+ kind: z.ZodLiteral<"skill-bonus">;
70
+ skills: z.ZodArray<z.ZodString>;
71
+ ability: z.ZodEnum<{
72
+ str: "str";
73
+ dex: "dex";
74
+ con: "con";
75
+ int: "int";
76
+ wis: "wis";
77
+ cha: "cha";
78
+ }>;
79
+ minimum: z.ZodOptional<z.ZodNumber>;
80
+ condition: z.ZodOptional<z.ZodString>;
81
+ subject: z.ZodOptional<z.ZodString>;
68
82
  }, z.core.$strip>, z.ZodObject<{
69
83
  kind: z.ZodLiteral<"immune-condition">;
70
84
  condition: z.ZodString;
@@ -364,6 +378,7 @@ export declare const optionalFeatureEntitySchema: z.ZodObject<{
364
378
  }, z.core.$strip>>>;
365
379
  consumes: z.ZodOptional<z.ZodNullable<z.ZodObject<{
366
380
  source: z.ZodOptional<z.ZodEnum<{
381
+ "spell-slots": "spell-slots";
367
382
  resource: "resource";
368
383
  "class-column": "class-column";
369
384
  "attack-dice": "attack-dice";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  optionalFeatureEntitySchema
3
- } from "../chunk-7WNQJAZW.js";
3
+ } from "../chunk-FYM3ROGA.js";
4
4
  import "../chunk-WYGD2UGN.js";
5
- import "../chunk-UA3I2YSO.js";
6
- import "../chunk-X3D6LXUU.js";
5
+ import "../chunk-ZJXSXVFP.js";
6
+ import "../chunk-VTKJOAJD.js";
7
7
  import "../chunk-UA5KS2PL.js";
8
8
  export {
9
9
  optionalFeatureEntitySchema
@@ -4,7 +4,7 @@ import {
4
4
  collectChosenAbilityPoints,
5
5
  collectChosenProficiencies,
6
6
  computeEffectiveProficiencies
7
- } from "../chunk-EYZCCWG2.js";
7
+ } from "../chunk-TEKRIRNZ.js";
8
8
  import "../chunk-4ISR76DH.js";
9
9
  import "../chunk-DPUJDOKV.js";
10
10
  import "../chunk-O4SRD3J5.js";
@@ -14,7 +14,7 @@ import "../chunk-YHYTW5QA.js";
14
14
  import "../chunk-MI7P3NX3.js";
15
15
  import "../chunk-PVCEA4HZ.js";
16
16
  import "../chunk-UBBKSYBY.js";
17
- import "../chunk-KPEJMNRD.js";
17
+ import "../chunk-IXMS2HHP.js";
18
18
  import "../chunk-TOM66P2P.js";
19
19
  import "../chunk-KU3YLF6D.js";
20
20
  import "../chunk-RLGQ5PZZ.js";
@@ -23,6 +23,17 @@ export interface WeaponAbilityOverride {
23
23
  */
24
24
  export interface FeatureEffectTotals {
25
25
  initiative_bonus: number;
26
+ initiative_terms: {
27
+ label: string;
28
+ value: number;
29
+ }[];
30
+ /** Ability-based numeric skill bonuses, resolved against final scores in recalc. */
31
+ skill_bonus_terms: {
32
+ skills: string[];
33
+ ability: Ability;
34
+ minimum: number;
35
+ label: string;
36
+ }[];
26
37
  hp_per_level_bonus: number;
27
38
  /** One term per hp-per-level-bonus effect, labeled with the owning feature's name. */
28
39
  hp_per_level_terms: {
@@ -30,6 +41,10 @@ export interface FeatureEffectTotals {
30
41
  value: number;
31
42
  }[];
32
43
  speed_walk_bonus: number;
44
+ speed_walk_terms: {
45
+ label: string;
46
+ value: number;
47
+ }[];
33
48
  /**
34
49
  * Absolute walk-speed FLOOR from `speed-bonus` effects with `set:true` (e.g.
35
50
  * a "base speed becomes 60" feature). Max across all set effects; 0 = none.
@@ -7,7 +7,7 @@ import {
7
7
  foldsNow,
8
8
  foldsOnSelf,
9
9
  selfEffectsOf
10
- } from "../chunk-KPEJMNRD.js";
10
+ } from "../chunk-IXMS2HHP.js";
11
11
  import "../chunk-TOM66P2P.js";
12
12
  import "../chunk-KU3YLF6D.js";
13
13
  import "../chunk-RLGQ5PZZ.js";
@@ -2,7 +2,7 @@ import {
2
2
  collectChosenProficiencies,
3
3
  collectProficiencyGrants,
4
4
  computeEffectiveProficiencies
5
- } from "../chunk-EYZCCWG2.js";
5
+ } from "../chunk-TEKRIRNZ.js";
6
6
  import "../chunk-4ISR76DH.js";
7
7
  import "../chunk-DPUJDOKV.js";
8
8
  import "../chunk-O4SRD3J5.js";
@@ -12,7 +12,7 @@ import "../chunk-YHYTW5QA.js";
12
12
  import "../chunk-MI7P3NX3.js";
13
13
  import "../chunk-PVCEA4HZ.js";
14
14
  import "../chunk-UBBKSYBY.js";
15
- import "../chunk-KPEJMNRD.js";
15
+ import "../chunk-IXMS2HHP.js";
16
16
  import "../chunk-TOM66P2P.js";
17
17
  import "../chunk-KU3YLF6D.js";
18
18
  import {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  collectChosenAbilityPoints,
6
6
  collectChosenProficiencies
7
- } from "../chunk-EYZCCWG2.js";
7
+ } from "../chunk-TEKRIRNZ.js";
8
8
  import {
9
9
  resourceLevelFor
10
10
  } from "../chunk-4ISR76DH.js";
@@ -39,7 +39,7 @@ import {
39
39
  computeFeatureEffects,
40
40
  foldsNow,
41
41
  selfEffectsOf
42
- } from "../chunk-KPEJMNRD.js";
42
+ } from "../chunk-IXMS2HHP.js";
43
43
  import "../chunk-TOM66P2P.js";
44
44
  import "../chunk-KU3YLF6D.js";
45
45
  import "../chunk-RLGQ5PZZ.js";
@@ -516,7 +516,7 @@ function computeProficiencies(resolved) {
516
516
  };
517
517
  }
518
518
  function recalc(resolved, registry) {
519
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
519
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y;
520
520
  const warnings = [];
521
521
  const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
522
522
  const chosenProfs = collectChosenProficiencies(resolved);
@@ -594,12 +594,19 @@ function recalc(resolved, registry) {
594
594
  for (const ab of featureEffects.proficiencies.saves) saveProfs.add(ab);
595
595
  for (const ab of chosenProfs.saves) saveProfs.add(ab);
596
596
  const saves = {};
597
+ const saveBreakdowns = {};
597
598
  for (const ab of ABILITY_KEYS) {
598
599
  const override = (_f = overrides.saves) == null ? void 0 : _f[ab];
599
600
  const prof = (_g = override == null ? void 0 : override.proficient) != null ? _g : saveProfs.has(ab);
600
601
  const derivedBonus = savingThrow(scores[ab], prof, proficiencyBonus) + applied.save_bonus + conditionEffects.d20_test_penalty;
601
602
  const bonus = (_h = override == null ? void 0 : override.bonus) != null ? _h : derivedBonus;
602
603
  saves[ab] = { bonus, proficient: prof };
604
+ saveBreakdowns[ab] = [
605
+ { source: ab.toUpperCase(), amount: mods[ab] },
606
+ ...prof ? [{ source: "Proficiency", amount: proficiencyBonus }] : [],
607
+ ...applied.save_bonus ? [{ source: "Equipment", amount: applied.save_bonus }] : [],
608
+ ...conditionEffects.d20_test_penalty ? [{ source: "Conditions", amount: conditionEffects.d20_test_penalty }] : []
609
+ ];
603
610
  }
604
611
  const profSet = /* @__PURE__ */ new Set([
605
612
  ...resolved.definition.skills.proficient,
@@ -609,12 +616,20 @@ function recalc(resolved, registry) {
609
616
  ]);
610
617
  const expSet = /* @__PURE__ */ new Set([...resolved.definition.skills.expertise, ...chosenProfs.expertise, ...featureEffects.proficiencies.skillExpertise]);
611
618
  const skills = {};
619
+ const skillBreakdowns = {};
612
620
  for (const skill of ALL_SKILLS) {
613
621
  const skillKey = skillSlugFromDisplay(skill);
614
622
  const ab = SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];
615
623
  const override = (_k = overrides.skills) == null ? void 0 : _k[skillKey];
616
624
  const tri = (_l = override == null ? void 0 : override.proficiency) != null ? _l : expSet.has(skillKey) ? "expertise" : profSet.has(skillKey) ? "proficient" : "none";
617
- const bonus = (_m = override == null ? void 0 : override.bonus) != null ? _m : skillBonus(scores[ab], tri, proficiencyBonus) + conditionEffects.d20_test_penalty;
625
+ const skillTerms = featureEffects.skill_bonus_terms.filter((t) => t.skills.includes(skillKey)).map((t) => ({ source: t.label, amount: Math.max(t.minimum, mods[t.ability]) }));
626
+ const bonus = (_m = override == null ? void 0 : override.bonus) != null ? _m : skillBonus(scores[ab], tri, proficiencyBonus) + skillTerms.reduce((sum, t) => sum + t.amount, 0) + conditionEffects.d20_test_penalty;
627
+ skillBreakdowns[skillKey] = [
628
+ { source: ab.toUpperCase(), amount: mods[ab] },
629
+ ...tri !== "none" ? [{ source: tri === "expertise" ? "Expertise" : "Proficiency", amount: proficiencyBonus * (tri === "expertise" ? 2 : 1) }] : [],
630
+ ...skillTerms,
631
+ ...conditionEffects.d20_test_penalty ? [{ source: "Conditions", amount: conditionEffects.d20_test_penalty }] : []
632
+ ];
618
633
  skills[skillKey] = {
619
634
  bonus,
620
635
  proficiency: tri,
@@ -710,10 +725,24 @@ function recalc(resolved, registry) {
710
725
  const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
711
726
  const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
712
727
  const speed = (_D = overrides.speed) != null ? _D : conditionSpeed;
728
+ const raceSpeed = (_G = (_F = (_E = resolved.race) == null ? void 0 : _E.speed) == null ? void 0 : _F.walk) != null ? _G : 30;
729
+ const speedBreakdown = [
730
+ { source: "Base speed", amount: raceSpeed },
731
+ ...speedFromRace(resolved) !== raceSpeed ? [{ source: "Feats", amount: speedFromRace(resolved) - raceSpeed }] : [],
732
+ ...applied.speed_bonuses.walk ? [{ source: "Equipment", amount: applied.speed_bonuses.walk }] : [],
733
+ ...featureEffects.speed_walk_terms.map((term) => ({ source: term.label, amount: term.value })),
734
+ ...baseSpeed > additiveSpeed ? [{ source: "Minimum speed", amount: baseSpeed - additiveSpeed }] : [],
735
+ ...conditionSpeed !== baseSpeed ? [{ source: "Conditions", amount: conditionSpeed - baseSpeed }] : []
736
+ ];
713
737
  if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
714
- const init = (_E = overrides.initiative) != null ? _E : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
738
+ const init = (_H = overrides.initiative) != null ? _H : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
739
+ const initiativeBreakdown = [
740
+ { source: "DEX", amount: mods.dex },
741
+ ...initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) !== mods.dex ? [{ source: "Feats", amount: initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) - mods.dex }] : [],
742
+ ...featureEffects.initiative_terms.map((term) => ({ source: term.label, amount: term.value }))
743
+ ];
715
744
  const senses = {
716
- darkvision: Math.max((_H = (_G = (_F = resolved.race) == null ? void 0 : _F.vision) == null ? void 0 : _G.darkvision) != null ? _H : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
745
+ darkvision: Math.max((_K = (_J = (_I = resolved.race) == null ? void 0 : _I.vision) == null ? void 0 : _J.darkvision) != null ? _K : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
717
746
  blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
718
747
  tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
719
748
  truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
@@ -760,27 +789,27 @@ function recalc(resolved, registry) {
760
789
  const spellLimits = computeSpellLimits(limitInputs);
761
790
  const defenses = {
762
791
  resistances: suppress(resolved, "resistances", composeDefenseEntries(
763
- (_J = (_I = resolved.definition.defenses) == null ? void 0 : _I.resistances) != null ? _J : [],
792
+ (_M = (_L = resolved.definition.defenses) == null ? void 0 : _L.resistances) != null ? _M : [],
764
793
  applied.defenses.resistances,
765
794
  featureEffects.resistances
766
795
  )),
767
796
  immunities: suppress(resolved, "immunities", composeDefenseEntries(
768
- (_L = (_K = resolved.definition.defenses) == null ? void 0 : _K.immunities) != null ? _L : [],
797
+ (_O = (_N = resolved.definition.defenses) == null ? void 0 : _N.immunities) != null ? _O : [],
769
798
  applied.defenses.immunities,
770
799
  featureEffects.immunities
771
800
  )),
772
801
  vulnerabilities: suppress(resolved, "vulnerabilities", composeDefenseEntries(
773
- (_N = (_M = resolved.definition.defenses) == null ? void 0 : _M.vulnerabilities) != null ? _N : [],
802
+ (_Q = (_P = resolved.definition.defenses) == null ? void 0 : _P.vulnerabilities) != null ? _Q : [],
774
803
  applied.defenses.vulnerabilities,
775
804
  featureEffects.vulnerabilities
776
805
  )),
777
806
  condition_immunities: suppress(resolved, "condition_immunities", composeDefenseEntries(
778
- (_P = (_O = resolved.definition.defenses) == null ? void 0 : _O.condition_immunities) != null ? _P : [],
807
+ (_S = (_R = resolved.definition.defenses) == null ? void 0 : _R.condition_immunities) != null ? _S : [],
779
808
  applied.defenses.condition_immunities,
780
809
  featureEffects.condition_immunities
781
810
  ))
782
811
  };
783
- const attackRows = [...(_Q = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _Q : [], buildUnarmedRow(mods, proficiencyBonus, resolveUnarmedStrike(resolved))];
812
+ const attackRows = [...(_T = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _T : [], buildUnarmedRow(mods, proficiencyBonus, resolveUnarmedStrike(resolved))];
784
813
  const riderBindings = {
785
814
  level: totalLevel,
786
815
  class_level: totalLevel,
@@ -801,6 +830,7 @@ function recalc(resolved, registry) {
801
830
  saves,
802
831
  proficiencies: profsForApply,
803
832
  skills,
833
+ statBreakdowns: { skills: skillBreakdowns, saves: saveBreakdowns, speed: speedBreakdown, initiative: initiativeBreakdown },
804
834
  passives,
805
835
  senses,
806
836
  hp: {
@@ -843,10 +873,10 @@ function recalc(resolved, registry) {
843
873
  ...riders.length ? { damageRiders: riders } : {}
844
874
  };
845
875
  }),
846
- equippedSlots: (_R = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _R : {},
847
- carriedWeight: (_S = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _S : 0,
848
- attunementUsed: (_T = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _T : 0,
849
- attunementLimit: (_V = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _V : (_U = overrides.attunement_limit) != null ? _U : Math.max(3, featureEffects.attunement_set),
876
+ equippedSlots: (_U = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _U : {},
877
+ carriedWeight: (_V = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _V : 0,
878
+ attunementUsed: (_W = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _W : 0,
879
+ attunementLimit: (_Y = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _Y : (_X = overrides.attunement_limit) != null ? _X : Math.max(3, featureEffects.attunement_set),
850
880
  conditionEffects,
851
881
  rollModifiers: featureEffects.rollModifiers,
852
882
  saveOutcomes: featureEffects.saveOutcomes
@@ -10,7 +10,7 @@ import {
10
10
  dedupeResolvedSpells,
11
11
  resolveOriginFeat,
12
12
  stripSlug
13
- } from "../chunk-EYZCCWG2.js";
13
+ } from "../chunk-TEKRIRNZ.js";
14
14
  import "../chunk-4ISR76DH.js";
15
15
  import "../chunk-DPUJDOKV.js";
16
16
  import "../chunk-O4SRD3J5.js";
@@ -20,7 +20,7 @@ import "../chunk-YHYTW5QA.js";
20
20
  import "../chunk-MI7P3NX3.js";
21
21
  import "../chunk-PVCEA4HZ.js";
22
22
  import "../chunk-UBBKSYBY.js";
23
- import "../chunk-KPEJMNRD.js";
23
+ import "../chunk-IXMS2HHP.js";
24
24
  import "../chunk-TOM66P2P.js";
25
25
  import "../chunk-KU3YLF6D.js";
26
26
  import "../chunk-RLGQ5PZZ.js";
@@ -744,6 +744,25 @@ export interface DerivedStats {
744
744
  proficiency: "none" | "proficient" | "expertise";
745
745
  ability: Ability;
746
746
  }>;
747
+ /** Numeric terms behind the sheet's skill, save, speed and initiative hovers. */
748
+ statBreakdowns?: {
749
+ skills: Partial<Record<SkillSlug, {
750
+ source: string;
751
+ amount: number;
752
+ }[]>>;
753
+ saves: Record<Ability, {
754
+ source: string;
755
+ amount: number;
756
+ }[]>;
757
+ speed: {
758
+ source: string;
759
+ amount: number;
760
+ }[];
761
+ initiative: {
762
+ source: string;
763
+ amount: number;
764
+ }[];
765
+ };
747
766
  passives: {
748
767
  perception: number;
749
768
  investigation: number;
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  raceCodec
3
- } from "../chunk-CQAL67R3.js";
4
- import "../chunk-7MRW4RTH.js";
5
- import "../chunk-2BI5NAXK.js";
3
+ } from "../chunk-HRG4URUK.js";
4
+ import "../chunk-5VTDYZIW.js";
5
+ import "../chunk-QCKOVD3K.js";
6
6
  import "../chunk-4U55VNC7.js";
7
- import "../chunk-JOVMV2X5.js";
7
+ import "../chunk-N4JJNGLZ.js";
8
8
  import "../chunk-WYGD2UGN.js";
9
- import "../chunk-UA3I2YSO.js";
10
- import "../chunk-IWRVOCT5.js";
11
- import "../chunk-X3D6LXUU.js";
9
+ import "../chunk-ZJXSXVFP.js";
10
+ import "../chunk-LEHDXPY6.js";
11
+ import "../chunk-VTKJOAJD.js";
12
12
  import "../chunk-UA5KS2PL.js";
13
13
  export {
14
14
  raceCodec
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  parseRace
3
- } from "../chunk-7MRW4RTH.js";
4
- import "../chunk-2BI5NAXK.js";
3
+ } from "../chunk-5VTDYZIW.js";
4
+ import "../chunk-QCKOVD3K.js";
5
5
  import "../chunk-4U55VNC7.js";
6
- import "../chunk-JOVMV2X5.js";
6
+ import "../chunk-N4JJNGLZ.js";
7
7
  import "../chunk-WYGD2UGN.js";
8
- import "../chunk-UA3I2YSO.js";
9
- import "../chunk-IWRVOCT5.js";
10
- import "../chunk-X3D6LXUU.js";
8
+ import "../chunk-ZJXSXVFP.js";
9
+ import "../chunk-LEHDXPY6.js";
10
+ import "../chunk-VTKJOAJD.js";
11
11
  import "../chunk-UA5KS2PL.js";
12
12
  export {
13
13
  parseRace
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  fixedAsiSchema,
3
3
  raceEntitySchema
4
- } from "../chunk-2BI5NAXK.js";
5
- import "../chunk-JOVMV2X5.js";
4
+ } from "../chunk-QCKOVD3K.js";
5
+ import "../chunk-N4JJNGLZ.js";
6
6
  import "../chunk-WYGD2UGN.js";
7
- import "../chunk-UA3I2YSO.js";
8
- import "../chunk-IWRVOCT5.js";
9
- import "../chunk-X3D6LXUU.js";
7
+ import "../chunk-ZJXSXVFP.js";
8
+ import "../chunk-LEHDXPY6.js";
9
+ import "../chunk-VTKJOAJD.js";
10
10
  import "../chunk-UA5KS2PL.js";
11
11
  export {
12
12
  fixedAsiSchema,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  choiceSchema
3
- } from "../chunk-IWRVOCT5.js";
4
- import "../chunk-X3D6LXUU.js";
3
+ } from "../chunk-LEHDXPY6.js";
4
+ import "../chunk-VTKJOAJD.js";
5
5
  export {
6
6
  choiceSchema
7
7
  };
@@ -4,6 +4,20 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
4
  value: z.ZodNumber;
5
5
  condition: z.ZodOptional<z.ZodString>;
6
6
  subject: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>, z.ZodObject<{
8
+ kind: z.ZodLiteral<"skill-bonus">;
9
+ skills: z.ZodArray<z.ZodString>;
10
+ ability: z.ZodEnum<{
11
+ str: "str";
12
+ dex: "dex";
13
+ con: "con";
14
+ int: "int";
15
+ wis: "wis";
16
+ cha: "cha";
17
+ }>;
18
+ minimum: z.ZodOptional<z.ZodNumber>;
19
+ condition: z.ZodOptional<z.ZodString>;
20
+ subject: z.ZodOptional<z.ZodString>;
7
21
  }, z.core.$strip>, z.ZodObject<{
8
22
  kind: z.ZodLiteral<"immune-condition">;
9
23
  condition: z.ZodString;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  featureEffectSchema
3
- } from "../chunk-X3D6LXUU.js";
3
+ } from "../chunk-VTKJOAJD.js";
4
4
  export {
5
5
  featureEffectSchema
6
6
  };
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  featureObjectSchema,
3
3
  featureSchema
4
- } from "../chunk-JOVMV2X5.js";
4
+ } from "../chunk-N4JJNGLZ.js";
5
5
  import "../chunk-WYGD2UGN.js";
6
- import "../chunk-UA3I2YSO.js";
7
- import "../chunk-IWRVOCT5.js";
8
- import "../chunk-X3D6LXUU.js";
6
+ import "../chunk-ZJXSXVFP.js";
7
+ import "../chunk-LEHDXPY6.js";
8
+ import "../chunk-VTKJOAJD.js";
9
9
  export {
10
10
  featureObjectSchema,
11
11
  featureSchema
@@ -111,6 +111,7 @@ export declare const resourceSchema: z.ZodObject<{
111
111
  * unguarded refine refuses all 231, measured). */
112
112
  export declare const resourceConsumptionSchema: z.ZodObject<{
113
113
  source: z.ZodOptional<z.ZodEnum<{
114
+ "spell-slots": "spell-slots";
114
115
  resource: "resource";
115
116
  "class-column": "class-column";
116
117
  "attack-dice": "attack-dice";
@@ -3,7 +3,7 @@ import {
3
3
  resetTriggerEnum,
4
4
  resourceConsumptionSchema,
5
5
  resourceSchema
6
- } from "../chunk-UA3I2YSO.js";
6
+ } from "../chunk-ZJXSXVFP.js";
7
7
  export {
8
8
  actionCostEnum,
9
9
  resetTriggerEnum,