@archivist-gg/dnd5e 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/background/background.codec.js +3 -3
- package/dist/background/background.parser.js +2 -2
- package/dist/background/background.schema.d.ts +8 -0
- package/dist/background/background.schema.js +5 -3
- package/dist/chunk-353WXS6S.js +25 -0
- package/dist/{chunk-DC74TZNA.js → chunk-4LZJXJJS.js} +7 -2
- package/dist/{chunk-DZXSWSBP.js → chunk-5ZBE4CWV.js} +1 -1
- package/dist/{chunk-IXZXFFFW.js → chunk-6IRYTM5V.js} +6 -1
- package/dist/chunk-7TEK5KK7.js +49 -0
- package/dist/{chunk-V6SOFUJW.js → chunk-AIRFC5NQ.js} +3 -1
- package/dist/{chunk-VTYUBINW.js → chunk-BIK4DFWK.js} +1 -1
- package/dist/{chunk-TQZB4OCJ.js → chunk-D3CLOBE3.js} +49 -21
- package/dist/{chunk-3TRGRSCH.js → chunk-LV4SNWZQ.js} +7 -1
- package/dist/{chunk-UC4FE5X3.js → chunk-N6N74K6X.js} +1 -1
- package/dist/chunk-O5EYMKFH.js +6 -0
- package/dist/{chunk-TUIFSVLI.js → chunk-SE7AZDR3.js} +1 -0
- package/dist/{chunk-5WQD3WNZ.js → chunk-TN6ZLTNU.js} +6 -5
- package/dist/{chunk-R5SQHP2X.js → chunk-TNUFPIXI.js} +48 -30
- package/dist/{chunk-J2RYSZMQ.js → chunk-VTTA2ALZ.js} +2 -2
- package/dist/class/class.slug.d.ts +7 -5
- package/dist/class/class.slug.js +1 -1
- package/dist/entities/base-item-resolver.d.ts +9 -0
- package/dist/entities/base-item-resolver.js +6 -4
- package/dist/entities/slug.d.ts +7 -0
- package/dist/entities/slug.js +3 -1
- package/dist/index.js +3902 -3623
- package/dist/item/item.actions-map.d.ts +8 -7
- package/dist/item/item.actions-map.js +3 -4
- package/dist/item/item.ai-schema.d.ts +1 -1
- package/dist/pc/pc.decision-engine.d.ts +13 -3
- package/dist/pc/pc.decision-engine.js +9 -9
- package/dist/pc/pc.equipment.js +6 -12
- package/dist/pc/pc.feature-effects.d.ts +5 -0
- package/dist/pc/pc.feature-effects.js +2 -11
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.js +7 -7
- package/dist/pc/pc.proficiencies.d.ts +31 -0
- package/dist/pc/pc.proficiencies.js +96 -23
- package/dist/pc/pc.proficiency-normalize.d.ts +5 -0
- package/dist/pc/pc.proficiency-query.js +5 -1
- package/dist/pc/pc.recalc.d.ts +7 -0
- package/dist/pc/pc.recalc.js +112 -58
- package/dist/pc/pc.resolver.js +7 -7
- package/dist/pc/pc.rest.d.ts +1 -1
- package/dist/pc/pc.rest.js +20 -11
- package/dist/pc/pc.schema.d.ts +10 -4
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.slotting.js +3 -3
- package/dist/pc/pc.spellcasting.d.ts +5 -1
- package/dist/pc/pc.spellcasting.js +4 -2
- package/dist/pc/pc.types.d.ts +30 -4
- package/dist/spell/spell.access.js +1 -1
- package/dist/types/choice.d.ts +5 -0
- package/dist/types/choice.js +9 -3
- package/dist/weapon/weapon.classify.d.ts +21 -0
- package/dist/weapon/weapon.classify.js +7 -0
- package/package.json +1 -1
- package/dist/chunk-BH6AMZVY.js +0 -25
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeConditionEffects
|
|
3
3
|
} from "../chunk-R2ZV233X.js";
|
|
4
|
-
import {
|
|
5
|
-
computeAppliedBonuses,
|
|
6
|
-
computeSlotsAndAttacks,
|
|
7
|
-
emptyAppliedBonuses
|
|
8
|
-
} from "../chunk-TQZB4OCJ.js";
|
|
9
|
-
import {
|
|
10
|
-
computeFeatureEffects
|
|
11
|
-
} from "../chunk-V6SOFUJW.js";
|
|
12
4
|
import {
|
|
13
5
|
collectChosenAbilityPoints,
|
|
14
6
|
collectChosenProficiencies
|
|
15
|
-
} from "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-UC4FE5X3.js";
|
|
7
|
+
} from "../chunk-TNUFPIXI.js";
|
|
8
|
+
import "../chunk-7TEK5KK7.js";
|
|
18
9
|
import {
|
|
19
10
|
computeSpellLimits,
|
|
20
11
|
deriveSpellSlots,
|
|
12
|
+
effectiveSpellcastingAbility,
|
|
21
13
|
resolveSpellcasting
|
|
22
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-6IRYTM5V.js";
|
|
23
15
|
import "../chunk-5XUXXAQJ.js";
|
|
24
16
|
import "../chunk-JEYQU3JT.js";
|
|
17
|
+
import {
|
|
18
|
+
computeAppliedBonuses,
|
|
19
|
+
computeSlotsAndAttacks,
|
|
20
|
+
emptyAppliedBonuses
|
|
21
|
+
} from "../chunk-D3CLOBE3.js";
|
|
22
|
+
import "../chunk-353WXS6S.js";
|
|
23
|
+
import "../chunk-O5EYMKFH.js";
|
|
24
|
+
import "../chunk-N6N74K6X.js";
|
|
25
|
+
import {
|
|
26
|
+
computeFeatureEffects
|
|
27
|
+
} from "../chunk-AIRFC5NQ.js";
|
|
25
28
|
import "../chunk-LWFTHJIE.js";
|
|
26
29
|
import "../chunk-DNAJRMNN.js";
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
+
import "../chunk-4LZJXJJS.js";
|
|
31
|
+
import "../chunk-LV4SNWZQ.js";
|
|
32
|
+
import "../chunk-VTTA2ALZ.js";
|
|
30
33
|
import {
|
|
31
34
|
abilityModifier,
|
|
32
35
|
attackBonus,
|
|
@@ -117,7 +120,7 @@ function abilityBonusBreakdown(resolved) {
|
|
|
117
120
|
}
|
|
118
121
|
return out;
|
|
119
122
|
}
|
|
120
|
-
function
|
|
123
|
+
function hitDiceAverageSum(classes) {
|
|
121
124
|
var _a;
|
|
122
125
|
let total = 0;
|
|
123
126
|
let firstLevelCounted = false;
|
|
@@ -126,14 +129,27 @@ function multiclassMaxHP(classes, conMod) {
|
|
|
126
129
|
if (!c.entity || die == null || c.level < 1) continue;
|
|
127
130
|
for (let lvl = 1; lvl <= c.level; lvl++) {
|
|
128
131
|
if (!firstLevelCounted) {
|
|
129
|
-
total += die
|
|
132
|
+
total += die;
|
|
130
133
|
firstLevelCounted = true;
|
|
131
134
|
} else {
|
|
132
|
-
total += Math.floor(die / 2) + 1
|
|
135
|
+
total += Math.floor(die / 2) + 1;
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
|
-
return
|
|
139
|
+
return total;
|
|
140
|
+
}
|
|
141
|
+
function hpLevelCount(classes) {
|
|
142
|
+
var _a;
|
|
143
|
+
let count = 0;
|
|
144
|
+
for (const c of classes) {
|
|
145
|
+
const die = parseDieSize((_a = c.entity) == null ? void 0 : _a.hit_die);
|
|
146
|
+
if (!c.entity || die == null || c.level < 1) continue;
|
|
147
|
+
count += c.level;
|
|
148
|
+
}
|
|
149
|
+
return count;
|
|
150
|
+
}
|
|
151
|
+
function multiclassMaxHP(classes, conMod) {
|
|
152
|
+
return Math.max(1, hitDiceAverageSum(classes) + conMod * hpLevelCount(classes));
|
|
137
153
|
}
|
|
138
154
|
function unarmoredAC(resolved, mods, warnings) {
|
|
139
155
|
return unarmoredACBreakdown(resolved, mods, warnings).total;
|
|
@@ -294,12 +310,18 @@ function computeAbilityScores(resolved, overrides) {
|
|
|
294
310
|
}
|
|
295
311
|
return out;
|
|
296
312
|
}
|
|
297
|
-
function
|
|
313
|
+
function normalizeArmorProf(input) {
|
|
298
314
|
var _a, _b;
|
|
299
315
|
if (!input) return { categories: [], specific: [] };
|
|
300
|
-
if (Array.isArray(input)) return { categories:
|
|
316
|
+
if (Array.isArray(input)) return { categories: input, specific: [] };
|
|
301
317
|
return { categories: (_a = input.categories) != null ? _a : [], specific: (_b = input.specific) != null ? _b : [] };
|
|
302
318
|
}
|
|
319
|
+
function normalizeWeaponToolProf(input) {
|
|
320
|
+
var _a, _b, _c;
|
|
321
|
+
if (!input) return { categories: [], specific: [] };
|
|
322
|
+
if (Array.isArray(input)) return { categories: [], specific: input };
|
|
323
|
+
return { categories: (_a = input.categories) != null ? _a : [], specific: ((_b = input.fixed) != null ? _b : []).concat((_c = input.specific) != null ? _c : []) };
|
|
324
|
+
}
|
|
303
325
|
function mergeInto(target, source) {
|
|
304
326
|
for (const c of source.categories) if (!target.categories.includes(c)) target.categories.push(c);
|
|
305
327
|
for (const s of source.specific) if (!target.specific.includes(s)) target.specific.push(s);
|
|
@@ -326,31 +348,31 @@ function computeProficiencies(resolved) {
|
|
|
326
348
|
for (const c of resolved.classes) {
|
|
327
349
|
const p = (_a = c.entity) == null ? void 0 : _a.proficiencies;
|
|
328
350
|
if (!p) continue;
|
|
329
|
-
mergeInto(armor,
|
|
330
|
-
mergeInto(weapons,
|
|
331
|
-
mergeInto(tools,
|
|
351
|
+
mergeInto(armor, normalizeArmorProf(p.armor));
|
|
352
|
+
mergeInto(weapons, normalizeWeaponToolProf(p.weapons));
|
|
353
|
+
mergeInto(tools, normalizeWeaponToolProf(p.tools));
|
|
332
354
|
(_b = p.languages) == null ? void 0 : _b.forEach((l) => languages.add(l));
|
|
333
355
|
}
|
|
334
356
|
const racePr = (_c = resolved.race) == null ? void 0 : _c.proficiencies;
|
|
335
357
|
if (racePr) {
|
|
336
|
-
mergeInto(armor,
|
|
337
|
-
mergeInto(weapons,
|
|
338
|
-
mergeInto(tools,
|
|
358
|
+
mergeInto(armor, normalizeArmorProf(racePr.armor));
|
|
359
|
+
mergeInto(weapons, normalizeWeaponToolProf(racePr.weapons));
|
|
360
|
+
mergeInto(tools, normalizeWeaponToolProf(racePr.tools));
|
|
339
361
|
(_d = racePr.languages) == null ? void 0 : _d.forEach((l) => languages.add(l));
|
|
340
362
|
}
|
|
341
363
|
const bgPr = (_e = resolved.background) == null ? void 0 : _e.proficiencies;
|
|
342
364
|
if (bgPr) {
|
|
343
|
-
mergeInto(armor,
|
|
344
|
-
mergeInto(weapons,
|
|
345
|
-
mergeInto(tools,
|
|
365
|
+
mergeInto(armor, normalizeArmorProf(bgPr.armor));
|
|
366
|
+
mergeInto(weapons, normalizeWeaponToolProf(bgPr.weapons));
|
|
367
|
+
mergeInto(tools, normalizeWeaponToolProf(bgPr.tools));
|
|
346
368
|
(_f = bgPr.languages) == null ? void 0 : _f.forEach((l) => languages.add(l));
|
|
347
369
|
}
|
|
348
370
|
for (const f of resolved.feats) {
|
|
349
371
|
const grants = f.grants_proficiency;
|
|
350
372
|
if (!grants) continue;
|
|
351
|
-
mergeInto(armor,
|
|
352
|
-
mergeInto(weapons,
|
|
353
|
-
mergeInto(tools,
|
|
373
|
+
mergeInto(armor, normalizeArmorProf(grants.armor));
|
|
374
|
+
mergeInto(weapons, normalizeWeaponToolProf(grants.weapons));
|
|
375
|
+
mergeInto(tools, normalizeWeaponToolProf(grants.tools));
|
|
354
376
|
(_g = grants.languages) == null ? void 0 : _g.forEach((l) => languages.add(l));
|
|
355
377
|
}
|
|
356
378
|
return {
|
|
@@ -362,7 +384,7 @@ function computeProficiencies(resolved) {
|
|
|
362
384
|
};
|
|
363
385
|
}
|
|
364
386
|
function recalc(resolved, registry) {
|
|
365
|
-
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;
|
|
387
|
+
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;
|
|
366
388
|
const warnings = [];
|
|
367
389
|
const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
|
|
368
390
|
const chosenProfs = collectChosenProficiencies(resolved);
|
|
@@ -484,9 +506,36 @@ function recalc(resolved, registry) {
|
|
|
484
506
|
investigation: (_t = (_s = overrides.passives) == null ? void 0 : _s.investigation) != null ? _t : passive(scores.int, investigationTri, proficiencyBonus),
|
|
485
507
|
insight: (_v = (_u = overrides.passives) == null ? void 0 : _u.insight) != null ? _v : passive(scores.wis, insightTri, proficiencyBonus)
|
|
486
508
|
};
|
|
487
|
-
const
|
|
488
|
-
const
|
|
489
|
-
const
|
|
509
|
+
const hpRolled = (_x = (_w = overrides.hp) == null ? void 0 : _w.rolled) != null ? _x : null;
|
|
510
|
+
const hpModifier = (_z = (_y = overrides.hp) == null ? void 0 : _y.modifier) != null ? _z : null;
|
|
511
|
+
const averageDiceSum = hitDiceAverageSum(resolved.classes);
|
|
512
|
+
const conLevels = hpLevelCount(resolved.classes);
|
|
513
|
+
const diceSum = hpRolled != null ? hpRolled : averageDiceSum;
|
|
514
|
+
const diceConRaw = diceSum + mods.con * conLevels;
|
|
515
|
+
const diceConClamped = Math.max(1, diceConRaw);
|
|
516
|
+
const hpMaxDerived = diceConClamped + featureEffects.hp_per_level_bonus * totalLevel + (hpModifier != null ? hpModifier : 0);
|
|
517
|
+
const hpMaxAfterConditions = Math.max(0, Math.floor(hpMaxDerived * conditionEffects.hp_max_multiplier));
|
|
518
|
+
const hpMax = (_B = (_A = overrides.hp) == null ? void 0 : _A.max) != null ? _B : hpMaxAfterConditions;
|
|
519
|
+
const hpBreakdown = {
|
|
520
|
+
diceSum,
|
|
521
|
+
diceSource: hpRolled != null ? "rolled" : "average",
|
|
522
|
+
averageDiceSum,
|
|
523
|
+
conMod: mods.con,
|
|
524
|
+
conLevels,
|
|
525
|
+
clampApplied: diceConClamped !== diceConRaw,
|
|
526
|
+
perLevelTerms: featureEffects.hp_per_level_terms.map((t) => ({
|
|
527
|
+
label: t.label,
|
|
528
|
+
perLevel: t.value,
|
|
529
|
+
levels: totalLevel,
|
|
530
|
+
total: t.value * totalLevel
|
|
531
|
+
})),
|
|
532
|
+
modifier: hpModifier,
|
|
533
|
+
exhaustionMultiplier: conditionEffects.hp_max_multiplier,
|
|
534
|
+
exhaustionLevel: conditionEffects.exhaustion_level,
|
|
535
|
+
derivedMax: hpMaxAfterConditions,
|
|
536
|
+
override: (_D = (_C = overrides.hp) == null ? void 0 : _C.max) != null ? _D : null,
|
|
537
|
+
final: hpMax
|
|
538
|
+
};
|
|
490
539
|
const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature" }));
|
|
491
540
|
const sumTerms = (terms) => terms.reduce((s, t) => s + t.amount, 0);
|
|
492
541
|
const weaponAbilities = [...featureEffects.weaponAbilities];
|
|
@@ -500,7 +549,7 @@ function recalc(resolved, registry) {
|
|
|
500
549
|
if (!c.entity) continue;
|
|
501
550
|
const profile = resolveSpellcasting(c);
|
|
502
551
|
if (profile) {
|
|
503
|
-
primaryCasterAbility = profile.ability;
|
|
552
|
+
primaryCasterAbility = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
|
|
504
553
|
break;
|
|
505
554
|
}
|
|
506
555
|
}
|
|
@@ -511,7 +560,7 @@ function recalc(resolved, registry) {
|
|
|
511
560
|
let acBreakdownDerived = [];
|
|
512
561
|
let acInformationalDerived = [];
|
|
513
562
|
if (registry) {
|
|
514
|
-
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (
|
|
563
|
+
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (_E = resolved.weaponMasteries) != null ? _E : []);
|
|
515
564
|
if (derivedEquipment.equippedSlots.armor) {
|
|
516
565
|
const featTerms = featureAcTermsFor(true);
|
|
517
566
|
acDerived = derivedEquipment.ac + sumTerms(featTerms);
|
|
@@ -534,16 +583,16 @@ function recalc(resolved, registry) {
|
|
|
534
583
|
acDerived = total + sumTerms(featTerms);
|
|
535
584
|
acBreakdownDerived = [...terms, ...featTerms];
|
|
536
585
|
}
|
|
537
|
-
const ac = (
|
|
586
|
+
const ac = (_F = overrides.ac) != null ? _F : acDerived;
|
|
538
587
|
const additiveSpeed = speedFromRace(resolved) + applied.speed_bonuses.walk + featureEffects.speed_walk_bonus;
|
|
539
588
|
const baseSpeed = Math.max(featureEffects.speed_walk_set, additiveSpeed);
|
|
540
589
|
const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
|
|
541
590
|
const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
|
|
542
|
-
const speed = (
|
|
591
|
+
const speed = (_G = overrides.speed) != null ? _G : conditionSpeed;
|
|
543
592
|
if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
|
|
544
|
-
const init = (
|
|
593
|
+
const init = (_H = overrides.initiative) != null ? _H : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
|
|
545
594
|
const senses = {
|
|
546
|
-
darkvision: Math.max((
|
|
595
|
+
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),
|
|
547
596
|
blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
|
|
548
597
|
tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
|
|
549
598
|
truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
|
|
@@ -555,19 +604,21 @@ function recalc(resolved, registry) {
|
|
|
555
604
|
if (!c.entity) continue;
|
|
556
605
|
const profile = resolveSpellcasting(c);
|
|
557
606
|
if (!profile) continue;
|
|
558
|
-
const
|
|
559
|
-
const
|
|
607
|
+
const ab = effectiveSpellcastingAbility(c.entity.slug, profile.ability, overrides);
|
|
608
|
+
const dc = saveDC(scores[ab], proficiencyBonus) + applied.spell_save_dc;
|
|
609
|
+
const atk = attackBonus(scores[ab], proficiencyBonus) + applied.spell_attack;
|
|
560
610
|
spellcastingClasses.push({
|
|
561
611
|
classSlug: c.entity.slug,
|
|
562
612
|
className: c.entity.name,
|
|
563
|
-
ability:
|
|
564
|
-
|
|
565
|
-
|
|
613
|
+
ability: ab,
|
|
614
|
+
defaultAbility: profile.ability,
|
|
615
|
+
saveDC: dc,
|
|
616
|
+
attackBonus: atk,
|
|
566
617
|
casterType: profile.casterType,
|
|
567
618
|
preparation: profile.preparation
|
|
568
619
|
});
|
|
569
620
|
slotInputs.push({ casterType: profile.casterType, level: c.level });
|
|
570
|
-
limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[
|
|
621
|
+
limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[ab] });
|
|
571
622
|
}
|
|
572
623
|
const spellcasting = spellcastingClasses.length > 0 ? {
|
|
573
624
|
ability: spellcastingClasses[0].ability,
|
|
@@ -587,20 +638,20 @@ function recalc(resolved, registry) {
|
|
|
587
638
|
const spellLimits = computeSpellLimits(limitInputs);
|
|
588
639
|
const defenses = {
|
|
589
640
|
resistances: dedupeDefenseList([
|
|
590
|
-
(
|
|
641
|
+
(_M = (_L = resolved.definition.defenses) == null ? void 0 : _L.resistances) != null ? _M : [],
|
|
591
642
|
applied.defenses.resistances,
|
|
592
643
|
featureEffects.resistances
|
|
593
644
|
]),
|
|
594
645
|
immunities: dedupeDefenseList([
|
|
595
|
-
(
|
|
646
|
+
(_O = (_N = resolved.definition.defenses) == null ? void 0 : _N.immunities) != null ? _O : [],
|
|
596
647
|
applied.defenses.immunities
|
|
597
648
|
]),
|
|
598
649
|
vulnerabilities: dedupeDefenseList([
|
|
599
|
-
(
|
|
650
|
+
(_Q = (_P = resolved.definition.defenses) == null ? void 0 : _P.vulnerabilities) != null ? _Q : [],
|
|
600
651
|
applied.defenses.vulnerabilities
|
|
601
652
|
]),
|
|
602
653
|
condition_immunities: dedupeDefenseList([
|
|
603
|
-
(
|
|
654
|
+
(_S = (_R = resolved.definition.defenses) == null ? void 0 : _R.condition_immunities) != null ? _S : [],
|
|
604
655
|
applied.defenses.condition_immunities,
|
|
605
656
|
featureEffects.condition_immunities
|
|
606
657
|
])
|
|
@@ -620,6 +671,7 @@ function recalc(resolved, registry) {
|
|
|
620
671
|
current: resolved.state.hp.current,
|
|
621
672
|
temp: resolved.state.hp.temp
|
|
622
673
|
},
|
|
674
|
+
hpBreakdown,
|
|
623
675
|
ac,
|
|
624
676
|
speed,
|
|
625
677
|
initiative: init,
|
|
@@ -643,7 +695,7 @@ function recalc(resolved, registry) {
|
|
|
643
695
|
// untouched rows keep `critRange`/`attackNotes` ABSENT (not 20 / not []).
|
|
644
696
|
// crit-range: folded weapon crit threshold, only when an effect lowered it.
|
|
645
697
|
// attackNotes: reroll-damage / attack-rule captions, only when non-empty.
|
|
646
|
-
attacks: ((
|
|
698
|
+
attacks: ((_T = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _T : []).map((a) => {
|
|
647
699
|
var _a2;
|
|
648
700
|
const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses];
|
|
649
701
|
return {
|
|
@@ -654,10 +706,10 @@ function recalc(resolved, registry) {
|
|
|
654
706
|
...riders.length ? { damageRiders: riders } : {}
|
|
655
707
|
};
|
|
656
708
|
}),
|
|
657
|
-
equippedSlots: (
|
|
658
|
-
carriedWeight: (
|
|
659
|
-
attunementUsed: (
|
|
660
|
-
attunementLimit: (
|
|
709
|
+
equippedSlots: (_U = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _U : {},
|
|
710
|
+
carriedWeight: (_V = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _V : 0,
|
|
711
|
+
attunementUsed: (_W = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _W : 0,
|
|
712
|
+
attunementLimit: (_Y = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _Y : (_X = overrides.attunement_limit) != null ? _X : 3,
|
|
661
713
|
conditionEffects,
|
|
662
714
|
rollModifiers: featureEffects.rollModifiers
|
|
663
715
|
};
|
|
@@ -669,6 +721,8 @@ export {
|
|
|
669
721
|
computeAbilityScores,
|
|
670
722
|
computeProficiencies,
|
|
671
723
|
flattenRaceAsi,
|
|
724
|
+
hitDiceAverageSum,
|
|
725
|
+
hpLevelCount,
|
|
672
726
|
initiativeBonus,
|
|
673
727
|
multiclassMaxHP,
|
|
674
728
|
parseDieSize,
|
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
dedupeResolvedSpells,
|
|
10
10
|
resolveOriginFeat,
|
|
11
11
|
stripSlug
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-IXZXFFFW.js";
|
|
12
|
+
} from "../chunk-TNUFPIXI.js";
|
|
13
|
+
import "../chunk-7TEK5KK7.js";
|
|
14
|
+
import "../chunk-6IRYTM5V.js";
|
|
16
15
|
import "../chunk-5XUXXAQJ.js";
|
|
17
16
|
import "../chunk-JEYQU3JT.js";
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
17
|
+
import "../chunk-N6N74K6X.js";
|
|
18
|
+
import "../chunk-4LZJXJJS.js";
|
|
19
|
+
import "../chunk-LV4SNWZQ.js";
|
|
20
|
+
import "../chunk-VTTA2ALZ.js";
|
|
21
21
|
import "../chunk-NAEPSZAM.js";
|
|
22
22
|
import "../chunk-WP2CX2JO.js";
|
|
23
23
|
export {
|
package/dist/pc/pc.rest.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EntityRegistry } from "@archivist-gg/core";
|
|
2
2
|
import type { Character, DerivedStats, ResolvedCharacter } from "./pc.types.js";
|
|
3
3
|
export type RestType = "short" | "long";
|
|
4
|
-
export type RestCategoryId = "hp-to-max" | "hd-regain" | "spell-slots" | "pact-slots" | "exhaustion" | `feature:${string}` | `item:${number}`;
|
|
4
|
+
export type RestCategoryId = "hp-to-max" | "hd-regain" | "spell-slots" | "pact-slots" | "exhaustion" | "hp-modifier-reset" | `feature:${string}` | `item:${number}`;
|
|
5
5
|
export interface RestCategory {
|
|
6
6
|
id: RestCategoryId;
|
|
7
7
|
label: string;
|
package/dist/pc/pc.rest.js
CHANGED
|
@@ -16,7 +16,7 @@ function findResourceById(resolved, id) {
|
|
|
16
16
|
return void 0;
|
|
17
17
|
}
|
|
18
18
|
function computeRestPlan(character, resolved, derived, registry, type) {
|
|
19
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
19
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
20
20
|
const cats = [];
|
|
21
21
|
let hdRegainDist;
|
|
22
22
|
const pact = character.state.spell_slots_pact;
|
|
@@ -38,16 +38,25 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
38
38
|
preview: `${character.state.exhaustion} \u2192 ${character.state.exhaustion - 1}`
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const hpModifier = (_b = (_a = character.overrides) == null ? void 0 : _a.hp) == null ? void 0 : _b.modifier;
|
|
42
|
+
if (hpModifier !== void 0) {
|
|
43
|
+
const signed = hpModifier > 0 ? `+${hpModifier}` : `${hpModifier}`;
|
|
44
|
+
cats.push({
|
|
45
|
+
id: "hp-modifier-reset",
|
|
46
|
+
label: "Max HP Modifier",
|
|
47
|
+
preview: `${signed} \u2192 cleared`
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const slotsUsed = Object.values((_c = character.state.spell_slots) != null ? _c : {}).reduce((s, slot) => {
|
|
42
51
|
var _a2;
|
|
43
52
|
return s + ((_a2 = slot.used) != null ? _a2 : 0);
|
|
44
53
|
}, 0);
|
|
45
54
|
if (slotsUsed > 0) {
|
|
46
55
|
cats.push({ id: "spell-slots", label: "Spell Slots", preview: "all reset" });
|
|
47
56
|
}
|
|
48
|
-
const totalLevel = (
|
|
57
|
+
const totalLevel = (_d = resolved.totalLevel) != null ? _d : 0;
|
|
49
58
|
const regainBudget = Math.max(1, Math.floor(totalLevel / 2));
|
|
50
|
-
const pools = Object.entries((
|
|
59
|
+
const pools = Object.entries((_e = character.state.hit_dice) != null ? _e : {}).map(([die, hd]) => ({ die, used: hd.used, total: hd.total })).filter((p) => p.used > 0).sort((a, b) => b.used - a.used);
|
|
51
60
|
if (pools.length > 0) {
|
|
52
61
|
let left = regainBudget;
|
|
53
62
|
const dist = [];
|
|
@@ -68,14 +77,14 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
68
77
|
hdRegainDist = dist.map((d) => ({ die: d.die, targetUsed: d.targetUsed }));
|
|
69
78
|
}
|
|
70
79
|
}
|
|
71
|
-
for (const [key, fu] of Object.entries((
|
|
80
|
+
for (const [key, fu] of Object.entries((_f = character.state.feature_uses) != null ? _f : {})) {
|
|
72
81
|
if (fu.used <= 0) continue;
|
|
73
82
|
const res = findResourceById(resolved, key);
|
|
74
|
-
const reset = (
|
|
83
|
+
const reset = (_g = res == null ? void 0 : res.reset) != null ? _g : "long-rest";
|
|
75
84
|
if (reset !== "short-rest" && reset !== "long-rest" && reset !== "dawn" && reset !== "dusk") continue;
|
|
76
85
|
cats.push({
|
|
77
86
|
id: `feature:${key}`,
|
|
78
|
-
label: (
|
|
87
|
+
label: (_h = res == null ? void 0 : res.label) != null ? _h : key,
|
|
79
88
|
preview: `${fu.used}/${fu.max} restored`
|
|
80
89
|
});
|
|
81
90
|
}
|
|
@@ -95,13 +104,13 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
95
104
|
});
|
|
96
105
|
}
|
|
97
106
|
if (type === "short") {
|
|
98
|
-
for (const [key, fu] of Object.entries((
|
|
107
|
+
for (const [key, fu] of Object.entries((_i = character.state.feature_uses) != null ? _i : {})) {
|
|
99
108
|
if (fu.used <= 0) continue;
|
|
100
109
|
const res = findResourceById(resolved, key);
|
|
101
|
-
if (((
|
|
110
|
+
if (((_j = res == null ? void 0 : res.reset) != null ? _j : "long-rest") !== "short-rest") continue;
|
|
102
111
|
cats.push({
|
|
103
112
|
id: `feature:${key}`,
|
|
104
|
-
label: (
|
|
113
|
+
label: (_k = res == null ? void 0 : res.label) != null ? _k : key,
|
|
105
114
|
preview: `${fu.used}/${fu.max} restored`
|
|
106
115
|
});
|
|
107
116
|
}
|
|
@@ -120,7 +129,7 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
120
129
|
});
|
|
121
130
|
});
|
|
122
131
|
}
|
|
123
|
-
const hdAvailable = type === "short" ? Object.entries((
|
|
132
|
+
const hdAvailable = type === "short" ? Object.entries((_l = character.state.hit_dice) != null ? _l : {}).filter(([, hd]) => hd.used < hd.total).map(([die, hd]) => ({ die, remaining: hd.total - hd.used })) : [];
|
|
124
133
|
return { type, categories: cats, hdAvailable, hdRegainDist };
|
|
125
134
|
}
|
|
126
135
|
export {
|
package/dist/pc/pc.schema.d.ts
CHANGED
|
@@ -221,14 +221,20 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
221
221
|
}, z.core.$strip>>;
|
|
222
222
|
hp: z.ZodOptional<z.ZodObject<{
|
|
223
223
|
max: z.ZodOptional<z.ZodNumber>;
|
|
224
|
+
rolled: z.ZodOptional<z.ZodNumber>;
|
|
225
|
+
modifier: z.ZodOptional<z.ZodNumber>;
|
|
224
226
|
}, z.core.$strip>>;
|
|
225
227
|
ac: z.ZodOptional<z.ZodNumber>;
|
|
226
228
|
speed: z.ZodOptional<z.ZodNumber>;
|
|
227
229
|
initiative: z.ZodOptional<z.ZodNumber>;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
spellcasting_ability_by_class: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
231
|
+
str: "str";
|
|
232
|
+
dex: "dex";
|
|
233
|
+
con: "con";
|
|
234
|
+
int: "int";
|
|
235
|
+
wis: "wis";
|
|
236
|
+
cha: "cha";
|
|
237
|
+
}>>>;
|
|
232
238
|
spellcasting_ability: z.ZodOptional<z.ZodEnum<{
|
|
233
239
|
str: "str";
|
|
234
240
|
dex: "dex";
|
package/dist/pc/pc.schema.js
CHANGED
package/dist/pc/pc.slotting.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
isShieldArmor,
|
|
7
7
|
isWeaponEntity,
|
|
8
8
|
resolveEntityForEntry
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-N6N74K6X.js";
|
|
10
|
+
import "../chunk-4LZJXJJS.js";
|
|
11
|
+
import "../chunk-LV4SNWZQ.js";
|
|
12
12
|
export {
|
|
13
13
|
defaultSlotForType,
|
|
14
14
|
effectiveArmor,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Ability } from "@archivist-gg/dnd5e";
|
|
2
|
-
import type { KnownSpellEntry, ResolvedClass } from "./pc.types.js";
|
|
2
|
+
import type { CharacterOverrides, KnownSpellEntry, ResolvedClass } from "./pc.types.js";
|
|
3
3
|
import type { CasterType } from "@archivist-gg/dnd5e/class/class.types";
|
|
4
4
|
export interface SpellcastingProfile {
|
|
5
5
|
ability: Ability;
|
|
@@ -18,6 +18,10 @@ export interface SpellcastingProfile {
|
|
|
18
18
|
* non-casters. No hardcoded class knowledge — everything comes from the data.
|
|
19
19
|
*/
|
|
20
20
|
export declare function resolveSpellcasting(rc: ResolvedClass): SpellcastingProfile | null;
|
|
21
|
+
/** The ability a class actually casts with: a per-class override wins, else the
|
|
22
|
+
* data ability from resolveSpellcasting. `dataAbility` is non-nullable by
|
|
23
|
+
* contract: resolve caster-ness (a non-null SpellcastingProfile) BEFORE calling. */
|
|
24
|
+
export declare function effectiveSpellcastingAbility(classSlug: string, dataAbility: Ability, overrides: CharacterOverrides): Ability;
|
|
21
25
|
export interface NormalizedKnownSpell {
|
|
22
26
|
slug: string;
|
|
23
27
|
classSlug: string | null;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeSpellLimits,
|
|
3
3
|
deriveSpellSlots,
|
|
4
|
+
effectiveSpellcastingAbility,
|
|
4
5
|
normalizeKnownSpell,
|
|
5
6
|
resolveSpellcasting
|
|
6
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-6IRYTM5V.js";
|
|
7
8
|
import "../chunk-5XUXXAQJ.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-VTTA2ALZ.js";
|
|
9
10
|
import "../chunk-NAEPSZAM.js";
|
|
10
11
|
import "../chunk-WP2CX2JO.js";
|
|
11
12
|
export {
|
|
12
13
|
computeSpellLimits,
|
|
13
14
|
deriveSpellSlots,
|
|
15
|
+
effectiveSpellcastingAbility,
|
|
14
16
|
normalizeKnownSpell,
|
|
15
17
|
resolveSpellcasting
|
|
16
18
|
};
|
package/dist/pc/pc.types.d.ts
CHANGED
|
@@ -120,14 +120,13 @@ export interface CharacterOverrides {
|
|
|
120
120
|
}>;
|
|
121
121
|
hp?: {
|
|
122
122
|
max?: number;
|
|
123
|
+
rolled?: number;
|
|
124
|
+
modifier?: number;
|
|
123
125
|
};
|
|
124
126
|
ac?: number;
|
|
125
127
|
speed?: number;
|
|
126
128
|
initiative?: number;
|
|
127
|
-
|
|
128
|
-
saveDC?: number;
|
|
129
|
-
attackBonus?: number;
|
|
130
|
-
};
|
|
129
|
+
spellcasting_ability_by_class?: Partial<Record<string, Ability>>;
|
|
131
130
|
/** Character-level spellcasting ability for spells that carry no ability of
|
|
132
131
|
* their own (e.g. a Spell Scroll cast by a non-caster): the DC-ability fallback
|
|
133
132
|
* after a per-instance override and the character's own class ability. */
|
|
@@ -339,6 +338,27 @@ export interface ACTerm {
|
|
|
339
338
|
amount: number;
|
|
340
339
|
kind: "armor" | "shield" | "item" | "unarmored" | "override" | "dex" | "ability" | "feature";
|
|
341
340
|
}
|
|
341
|
+
/** Structured max-HP math for the Max HP modal. Spec: P5 2026-07-21. */
|
|
342
|
+
export interface HPBreakdown {
|
|
343
|
+
diceSum: number;
|
|
344
|
+
diceSource: "rolled" | "average";
|
|
345
|
+
averageDiceSum: number;
|
|
346
|
+
conMod: number;
|
|
347
|
+
conLevels: number;
|
|
348
|
+
clampApplied: boolean;
|
|
349
|
+
perLevelTerms: {
|
|
350
|
+
label: string;
|
|
351
|
+
perLevel: number;
|
|
352
|
+
levels: number;
|
|
353
|
+
total: number;
|
|
354
|
+
}[];
|
|
355
|
+
modifier: number | null;
|
|
356
|
+
exhaustionMultiplier: number;
|
|
357
|
+
exhaustionLevel: number;
|
|
358
|
+
derivedMax: number;
|
|
359
|
+
override: number | null;
|
|
360
|
+
final: number;
|
|
361
|
+
}
|
|
342
362
|
/** An additive on-hit damage rider (dice or flat) applied to an attack, from a
|
|
343
363
|
* feature (global — all weapon attacks) or a magic item (that weapon only).
|
|
344
364
|
* `amount` is a dice/flat string ("2d6", "1d8", "2"); `damage_type` optional
|
|
@@ -353,6 +373,10 @@ export interface AttackRow {
|
|
|
353
373
|
id: string;
|
|
354
374
|
name: string;
|
|
355
375
|
range?: string;
|
|
376
|
+
/** Secondary thrown-mode range ("20/60 ft") for a throwable melee weapon.
|
|
377
|
+
* Display-only; rendered as a stacked muted second line in the Range cell.
|
|
378
|
+
* Absent otherwise. */
|
|
379
|
+
thrownRange?: string;
|
|
356
380
|
toHit: number;
|
|
357
381
|
damageDice: string;
|
|
358
382
|
damageType: string;
|
|
@@ -529,6 +553,7 @@ export interface DerivedStats {
|
|
|
529
553
|
condition_immunities: string[];
|
|
530
554
|
};
|
|
531
555
|
acBreakdown: ACTerm[];
|
|
556
|
+
hpBreakdown: HPBreakdown;
|
|
532
557
|
acInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
|
|
533
558
|
/** Situational saving-throw bonuses (e.g. +1 vs spells) for save tooltips. */
|
|
534
559
|
savesInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
|
|
@@ -557,6 +582,7 @@ export interface SpellcastingClassInfo {
|
|
|
557
582
|
classSlug: string;
|
|
558
583
|
className: string;
|
|
559
584
|
ability: Ability;
|
|
585
|
+
defaultAbility: Ability;
|
|
560
586
|
saveDC: number;
|
|
561
587
|
attackBonus: number;
|
|
562
588
|
casterType: "full" | "half" | "third" | "pact";
|
package/dist/types/choice.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import type { FeatureEffect } from "./feature-effect.js";
|
|
|
3
3
|
export type Ability = keyof Abilities;
|
|
4
4
|
export type SkillSlug = "acrobatics" | "animal-handling" | "arcana" | "athletics" | "deception" | "history" | "insight" | "intimidation" | "investigation" | "medicine" | "nature" | "perception" | "performance" | "persuasion" | "religion" | "sleight-of-hand" | "stealth" | "survival";
|
|
5
5
|
export declare const ALL_SKILL_SLUGS: SkillSlug[];
|
|
6
|
+
/** The SRD language set: 8 standard + 8 exotic. Authoritative and reused as
|
|
7
|
+
* KNOWN_LANGUAGES by the proficiency aggregate; slugs are edition-agnostic. */
|
|
8
|
+
export declare const STANDARD_LANGUAGES: string[];
|
|
9
|
+
export declare const EXOTIC_LANGUAGES: string[];
|
|
10
|
+
export declare const ALL_LANGUAGES: string[];
|
|
6
11
|
export type FeatCategory = "origin" | "general" | "fighting-style" | "epic-boon";
|
|
7
12
|
/** Closed, enumerated registry filter — YAML can never express a query the
|
|
8
13
|
* engine would apply unsafely. `"self"` resolves against the owning
|
package/dist/types/choice.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ALL_LANGUAGES,
|
|
3
|
+
ALL_SKILL_SLUGS,
|
|
4
|
+
EXOTIC_LANGUAGES,
|
|
5
|
+
STANDARD_LANGUAGES
|
|
6
|
+
} from "../chunk-7TEK5KK7.js";
|
|
4
7
|
export {
|
|
5
|
-
|
|
8
|
+
ALL_LANGUAGES,
|
|
9
|
+
ALL_SKILL_SLUGS,
|
|
10
|
+
EXOTIC_LANGUAGES,
|
|
11
|
+
STANDARD_LANGUAGES
|
|
6
12
|
};
|