@archivist-gg/dnd5e 0.3.10 → 0.3.11
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/{chunk-HLQAFZKQ.js → chunk-2INMRR3Q.js} +2 -2
- package/dist/{chunk-MI7P3NX3.js → chunk-3HX5VLWP.js} +1 -1
- package/dist/{chunk-3UNP3G4D.js → chunk-CHUALUIX.js} +1 -1
- package/dist/{chunk-JSZ4H6AQ.js → chunk-MWCCGPG3.js} +1 -1
- package/dist/{chunk-22MOUU2G.js → chunk-T2SNEJOE.js} +1 -1
- package/dist/{chunk-OYUEUKKF.js → chunk-U3BABVJF.js} +10 -6
- package/dist/{chunk-OZP6JFGT.js → chunk-XY6X2APM.js} +3 -1
- package/dist/{chunk-VQAXTIBW.js → chunk-ZDAEGJH4.js} +2 -0
- package/dist/feat/feat.codec.js +3 -3
- package/dist/feat/feat.parser.js +2 -2
- package/dist/feat/feat.schema.js +1 -1
- package/dist/index.js +306 -120
- package/dist/pc/pc.additional-spells.js +3 -3
- package/dist/pc/pc.decision-engine.js +4 -4
- package/dist/pc/pc.proficiencies.js +4 -4
- package/dist/pc/pc.recalc.js +4 -4
- package/dist/pc/pc.resolver.js +4 -4
- package/dist/spell/spell.codec.js +3 -3
- package/dist/spell/spell.parser.js +2 -2
- package/dist/spell/spell.scaling.d.ts +34 -10
- package/dist/spell/spell.scaling.js +36 -4
- package/dist/spell/spell.schema.d.ts +1 -0
- package/dist/spell/spell.schema.js +1 -1
- package/dist/spell/spell.types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
prefixOf,
|
|
6
6
|
raceIsUngated,
|
|
7
7
|
resolveSpellByName
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-3HX5VLWP.js";
|
|
9
9
|
import "../chunk-PVCEA4HZ.js";
|
|
10
10
|
import "../chunk-LVQLWRCU.js";
|
|
11
11
|
import "../chunk-6X4KUDMU.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-XY6X2APM.js";
|
|
13
|
+
import "../chunk-ZDAEGJH4.js";
|
|
14
14
|
import "../chunk-WELIKLZF.js";
|
|
15
15
|
import "../chunk-UA5KS2PL.js";
|
|
16
16
|
export {
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
collectChosenAbilityPoints,
|
|
5
5
|
collectChosenProficiencies,
|
|
6
6
|
computeEffectiveProficiencies
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-2INMRR3Q.js";
|
|
8
8
|
import "../chunk-4ISR76DH.js";
|
|
9
9
|
import "../chunk-DPUJDOKV.js";
|
|
10
10
|
import "../chunk-O4SRD3J5.js";
|
|
11
11
|
import "../chunk-PP2UHLBA.js";
|
|
12
12
|
import "../chunk-IUAAXXNO.js";
|
|
13
13
|
import "../chunk-YHYTW5QA.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-3HX5VLWP.js";
|
|
15
15
|
import "../chunk-PVCEA4HZ.js";
|
|
16
16
|
import "../chunk-UBBKSYBY.js";
|
|
17
17
|
import "../chunk-CBEKVAX4.js";
|
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
import "../chunk-YBLDE5CG.js";
|
|
27
27
|
import "../chunk-EVMUJYUD.js";
|
|
28
28
|
import "../chunk-VTTA2ALZ.js";
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-XY6X2APM.js";
|
|
30
|
+
import "../chunk-ZDAEGJH4.js";
|
|
31
31
|
import "../chunk-PDJSUH24.js";
|
|
32
32
|
import "../chunk-WELIKLZF.js";
|
|
33
33
|
import "../chunk-4U55VNC7.js";
|
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
collectChosenProficiencies,
|
|
3
3
|
collectProficiencyGrants,
|
|
4
4
|
computeEffectiveProficiencies
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-2INMRR3Q.js";
|
|
6
6
|
import "../chunk-4ISR76DH.js";
|
|
7
7
|
import "../chunk-DPUJDOKV.js";
|
|
8
8
|
import "../chunk-O4SRD3J5.js";
|
|
9
9
|
import "../chunk-PP2UHLBA.js";
|
|
10
10
|
import "../chunk-IUAAXXNO.js";
|
|
11
11
|
import "../chunk-YHYTW5QA.js";
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-3HX5VLWP.js";
|
|
13
13
|
import "../chunk-PVCEA4HZ.js";
|
|
14
14
|
import "../chunk-UBBKSYBY.js";
|
|
15
15
|
import "../chunk-CBEKVAX4.js";
|
|
@@ -25,8 +25,8 @@ import "../chunk-6X4KUDMU.js";
|
|
|
25
25
|
import "../chunk-YBLDE5CG.js";
|
|
26
26
|
import "../chunk-EVMUJYUD.js";
|
|
27
27
|
import "../chunk-VTTA2ALZ.js";
|
|
28
|
-
import "../chunk-
|
|
29
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-XY6X2APM.js";
|
|
29
|
+
import "../chunk-ZDAEGJH4.js";
|
|
30
30
|
import "../chunk-PDJSUH24.js";
|
|
31
31
|
import "../chunk-WELIKLZF.js";
|
|
32
32
|
import "../chunk-4U55VNC7.js";
|
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
collectChosenAbilityPoints,
|
|
6
6
|
collectChosenProficiencies
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-2INMRR3Q.js";
|
|
8
8
|
import {
|
|
9
9
|
resourceLevelFor
|
|
10
10
|
} from "../chunk-4ISR76DH.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
unarmedDieColumnFor
|
|
22
22
|
} from "../chunk-IUAAXXNO.js";
|
|
23
23
|
import "../chunk-YHYTW5QA.js";
|
|
24
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-3HX5VLWP.js";
|
|
25
25
|
import "../chunk-PVCEA4HZ.js";
|
|
26
26
|
import {
|
|
27
27
|
toDefenseSlug
|
|
@@ -54,8 +54,8 @@ import {
|
|
|
54
54
|
isValidMaxFormula
|
|
55
55
|
} from "../chunk-EVMUJYUD.js";
|
|
56
56
|
import "../chunk-VTTA2ALZ.js";
|
|
57
|
-
import "../chunk-
|
|
58
|
-
import "../chunk-
|
|
57
|
+
import "../chunk-XY6X2APM.js";
|
|
58
|
+
import "../chunk-ZDAEGJH4.js";
|
|
59
59
|
import {
|
|
60
60
|
abilityModifier,
|
|
61
61
|
attackBonus,
|
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
dedupeResolvedSpells,
|
|
11
11
|
resolveOriginFeat,
|
|
12
12
|
stripSlug
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-2INMRR3Q.js";
|
|
14
14
|
import "../chunk-4ISR76DH.js";
|
|
15
15
|
import "../chunk-DPUJDOKV.js";
|
|
16
16
|
import "../chunk-O4SRD3J5.js";
|
|
17
17
|
import "../chunk-PP2UHLBA.js";
|
|
18
18
|
import "../chunk-IUAAXXNO.js";
|
|
19
19
|
import "../chunk-YHYTW5QA.js";
|
|
20
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-3HX5VLWP.js";
|
|
21
21
|
import "../chunk-PVCEA4HZ.js";
|
|
22
22
|
import "../chunk-UBBKSYBY.js";
|
|
23
23
|
import "../chunk-CBEKVAX4.js";
|
|
@@ -30,8 +30,8 @@ import "../chunk-6X4KUDMU.js";
|
|
|
30
30
|
import "../chunk-YBLDE5CG.js";
|
|
31
31
|
import "../chunk-EVMUJYUD.js";
|
|
32
32
|
import "../chunk-VTTA2ALZ.js";
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-XY6X2APM.js";
|
|
34
|
+
import "../chunk-ZDAEGJH4.js";
|
|
35
35
|
import "../chunk-PDJSUH24.js";
|
|
36
36
|
import "../chunk-WELIKLZF.js";
|
|
37
37
|
import "../chunk-4U55VNC7.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
spellCodec
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-MWCCGPG3.js";
|
|
4
|
+
import "../chunk-XY6X2APM.js";
|
|
5
|
+
import "../chunk-ZDAEGJH4.js";
|
|
6
6
|
import "../chunk-UA5KS2PL.js";
|
|
7
7
|
export {
|
|
8
8
|
spellCodec
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
normalizeSpellComponents,
|
|
4
4
|
normalizeSpellDuration,
|
|
5
5
|
parseSpell
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-XY6X2APM.js";
|
|
7
|
+
import "../chunk-ZDAEGJH4.js";
|
|
8
8
|
import "../chunk-UA5KS2PL.js";
|
|
9
9
|
export {
|
|
10
10
|
mirrorSpellShapes,
|
|
@@ -9,16 +9,39 @@ export interface SpellEffectParts {
|
|
|
9
9
|
/** As printed: the roll, `"<N> targets"`, the duration, or the authored sentence verbatim. */
|
|
10
10
|
value: string;
|
|
11
11
|
}
|
|
12
|
+
/** The spell's base roll (`damage_roll`), trimmed, or null when absent, empty or whitespace-only. The ONE base-roll
|
|
13
|
+
* check: every reader of `damage_roll` (the scaling readers here, the spell card) goes through it. */
|
|
14
|
+
export declare function spellBaseRoll(spell: Spell): string | null;
|
|
12
15
|
/**
|
|
13
|
-
* At-a-glance
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* At-a-glance effect for casting a LEVELLED `spell` with a slot of `slotLevel`, WITH the field
|
|
17
|
+
* it came from. Returns null when absent or untrustworthy.
|
|
18
|
+
*
|
|
19
|
+
* A structured `casting_options` entry for that slot (`type: "slot_level_<N>"`) wins: the FIRST
|
|
20
|
+
* present field, in this order: `damage_roll`, `target_count`, `duration`, `desc` (so an option
|
|
21
|
+
* carrying a roll AND a sentence yields the roll). A `target_count` that equals the slot level is
|
|
22
|
+
* the known SRD-2014 bad encoding (e.g. Magic Missile 2nd->2 instead of 4) and is suppressed.
|
|
23
|
+
*
|
|
24
|
+
* With no option for the slot, the spell's BASE roll (`damage_roll`) answers at the spell's OWN
|
|
25
|
+
* level only. Above it, whether the base roll is still the roll dealt is `spellBaseRollAtSlot`'s
|
|
26
|
+
* question (it is when the damage does not scale); a SCALING spell missing its option above base
|
|
27
|
+
* stays null here. A CANTRIP is never read by slot (null): its roll follows the character's level,
|
|
28
|
+
* `spellEffectAtCharacterLevel`, even when it is cast from a scroll. This errs toward showing
|
|
29
|
+
* nothing rather than a wrong number.
|
|
20
30
|
*/
|
|
21
31
|
export declare function spellEffectPartsAtSlot(spell: Spell, slotLevel: number): SpellEffectParts | null;
|
|
32
|
+
/**
|
|
33
|
+
* The spell's BASE roll at a slot of `slotLevel` when the data PROVES its damage does not scale, so every slot at or
|
|
34
|
+
* above the spell's level deals the base roll. Two proofs, and only these:
|
|
35
|
+
* (a) it has `slot_level_<N>` options and every one carries only a `duration` and / or a `target_count` (plus the
|
|
36
|
+
* `concentration` flag a duration carries): 2024 Hex and Hunter's Mark scale their duration, Magic Missile and
|
|
37
|
+
* Scorching Ray their target count;
|
|
38
|
+
* (b) it has no slot options AND no `at_higher_levels` text (Finger of Death).
|
|
39
|
+
* Anything else is NOT proof: prose-only scaling (2014 Cure Wounds' "increases by 1d8 for each slot level above
|
|
40
|
+
* 1st", with no options) would print the unscaled base on every upcast row, so it stays null there. The companion of
|
|
41
|
+
* `spellEffectPartsAtSlot`: a row prints this roll beside a target count, and the duration a slot option carries
|
|
42
|
+
* prints in its own cell. Null for a cantrip, below the spell's level, and when the spell has no base roll.
|
|
43
|
+
*/
|
|
44
|
+
export declare function spellBaseRollAtSlot(spell: Spell, slotLevel: number): string | null;
|
|
22
45
|
/** The value of `spellEffectPartsAtSlot`, without its field. */
|
|
23
46
|
export declare function spellEffectAtSlot(spell: Spell, slotLevel: number): string | null;
|
|
24
47
|
/**
|
|
@@ -26,9 +49,10 @@ export declare function spellEffectAtSlot(spell: Spell, slotLevel: number): stri
|
|
|
26
49
|
* `casting_options` (`type: "player_level_<N>"`). The roll of the HIGHEST `N <= characterLevel` wins: SRD 5e authors
|
|
27
50
|
* one option per level from 5 to 20, SRD 2024 and the converter author only 5 / 11 / 17. An option with no roll or an
|
|
28
51
|
* EMPTY one never qualifies (SRD 5e Acid Splash and Poison Spray open with `player_level_2..4` carrying
|
|
29
|
-
* `damage_roll: ''`; Eldritch Blast 2024 authors `target_count` only).
|
|
30
|
-
*
|
|
31
|
-
*
|
|
52
|
+
* `damage_roll: ''`; Eldritch Blast 2024 authors `target_count` only). When no tier qualifies (below the first tier,
|
|
53
|
+
* or tiers that carry no roll) the spell's BASE roll `damage_roll` answers: the tier-1 roll (Fire Bolt `1d10` at 4,
|
|
54
|
+
* Eldritch Blast's per-beam `1d10` at any level). Null for a levelled spell, for a level that is not a finite number
|
|
55
|
+
* (a fixture-built `derived` omits `totalLevel`), and when neither a tier nor a non-empty base roll exists.
|
|
32
56
|
*/
|
|
33
57
|
export declare function spellEffectAtCharacterLevel(spell: Spell, characterLevel: number): string | null;
|
|
34
58
|
/** Owned slot levels strictly above the spell's base level (scaling spells only). */
|
|
@@ -3,10 +3,19 @@ function spellScales(spell) {
|
|
|
3
3
|
var _a, _b, _c, _d;
|
|
4
4
|
return ((_b = (_a = spell.casting_options) == null ? void 0 : _a.length) != null ? _b : 0) > 0 || ((_d = (_c = spell.at_higher_levels) == null ? void 0 : _c.length) != null ? _d : 0) > 0;
|
|
5
5
|
}
|
|
6
|
+
function spellBaseRoll(spell) {
|
|
7
|
+
const roll = typeof spell.damage_roll === "string" ? spell.damage_roll.trim() : "";
|
|
8
|
+
return roll !== "" ? roll : null;
|
|
9
|
+
}
|
|
6
10
|
function spellEffectPartsAtSlot(spell, slotLevel) {
|
|
7
|
-
var _a;
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const base = (_a = spell.level) != null ? _a : 0;
|
|
13
|
+
if (base === 0) return null;
|
|
14
|
+
const opt = ((_b = spell.casting_options) != null ? _b : []).find((o) => o.type === `slot_level_${slotLevel}`);
|
|
15
|
+
if (!opt) {
|
|
16
|
+
const roll = spellBaseRoll(spell);
|
|
17
|
+
return roll !== null && slotLevel === base ? { field: "damage_roll", value: roll } : null;
|
|
18
|
+
}
|
|
10
19
|
if (opt.damage_roll) return { field: "damage_roll", value: opt.damage_roll };
|
|
11
20
|
if (typeof opt.target_count === "number") {
|
|
12
21
|
if (opt.target_count === slotLevel) return null;
|
|
@@ -15,6 +24,27 @@ function spellEffectPartsAtSlot(spell, slotLevel) {
|
|
|
15
24
|
if (opt.duration) return { field: "duration", value: opt.duration };
|
|
16
25
|
return opt.desc != null ? { field: "desc", value: opt.desc } : null;
|
|
17
26
|
}
|
|
27
|
+
var NON_ROLL_SCALES = /* @__PURE__ */ new Set(["duration", "target_count"]);
|
|
28
|
+
var NON_ROLL_OPTION_FIELDS = /* @__PURE__ */ new Set([...NON_ROLL_SCALES, "concentration"]);
|
|
29
|
+
function spellBaseRollAtSlot(spell, slotLevel) {
|
|
30
|
+
var _a, _b, _c;
|
|
31
|
+
const base = (_a = spell.level) != null ? _a : 0;
|
|
32
|
+
if (base === 0 || slotLevel < base) return null;
|
|
33
|
+
const roll = spellBaseRoll(spell);
|
|
34
|
+
if (roll === null) return null;
|
|
35
|
+
const slotOptions = ((_b = spell.casting_options) != null ? _b : []).filter((o) => {
|
|
36
|
+
var _a2;
|
|
37
|
+
return /^slot_level_\d+$/.test(String((_a2 = o.type) != null ? _a2 : ""));
|
|
38
|
+
});
|
|
39
|
+
if (slotOptions.length > 0) {
|
|
40
|
+
const onlyNonRoll = slotOptions.every((o) => {
|
|
41
|
+
const fields = Object.entries(o).filter(([k, v]) => k !== "type" && v != null).map(([k]) => k);
|
|
42
|
+
return fields.some((k) => NON_ROLL_SCALES.has(k)) && fields.every((k) => NON_ROLL_OPTION_FIELDS.has(k));
|
|
43
|
+
});
|
|
44
|
+
return onlyNonRoll ? roll : null;
|
|
45
|
+
}
|
|
46
|
+
return ((_c = spell.at_higher_levels) != null ? _c : []).some((t) => typeof t === "string" && t.trim() !== "") ? null : roll;
|
|
47
|
+
}
|
|
18
48
|
function spellEffectAtSlot(spell, slotLevel) {
|
|
19
49
|
var _a, _b;
|
|
20
50
|
return (_b = (_a = spellEffectPartsAtSlot(spell, slotLevel)) == null ? void 0 : _a.value) != null ? _b : null;
|
|
@@ -30,7 +60,7 @@ function spellEffectAtCharacterLevel(spell, characterLevel) {
|
|
|
30
60
|
const n = Number(m[1]);
|
|
31
61
|
if (n <= characterLevel && (best === null || n > best.n)) best = { n, roll: opt.damage_roll };
|
|
32
62
|
}
|
|
33
|
-
return best ? best.roll :
|
|
63
|
+
return best ? best.roll : spellBaseRoll(spell);
|
|
34
64
|
}
|
|
35
65
|
function upcastLevelsFor(spell, ownedSlotLevels) {
|
|
36
66
|
var _a;
|
|
@@ -39,6 +69,8 @@ function upcastLevelsFor(spell, ownedSlotLevels) {
|
|
|
39
69
|
return ownedSlotLevels.filter((l) => l > base).sort((a, b) => a - b);
|
|
40
70
|
}
|
|
41
71
|
export {
|
|
72
|
+
spellBaseRoll,
|
|
73
|
+
spellBaseRollAtSlot,
|
|
42
74
|
spellEffectAtCharacterLevel,
|
|
43
75
|
spellEffectAtSlot,
|
|
44
76
|
spellEffectPartsAtSlot,
|
|
@@ -40,6 +40,7 @@ export declare const spellEntitySchema: z.ZodObject<{
|
|
|
40
40
|
damage: z.ZodOptional<z.ZodObject<{
|
|
41
41
|
types: z.ZodArray<z.ZodString>;
|
|
42
42
|
}, z.core.$strip>>;
|
|
43
|
+
damage_roll: z.ZodOptional<z.ZodString>;
|
|
43
44
|
saving_throw: z.ZodOptional<z.ZodObject<{
|
|
44
45
|
ability: z.ZodString;
|
|
45
46
|
}, z.core.$strip>>;
|
|
@@ -16,6 +16,10 @@ export interface Spell {
|
|
|
16
16
|
damage?: {
|
|
17
17
|
types: string[];
|
|
18
18
|
};
|
|
19
|
+
/** The BASE roll: the roll at the spell's own level, or a cantrip's tier-1 roll (before its first
|
|
20
|
+
* `player_level_<N>` option). Like `casting_options[].damage_roll` it also carries healing rolls
|
|
21
|
+
* (Cure Wounds `2d8`). Mirrors Open5e v2's top-level `damage_roll`. */
|
|
22
|
+
damage_roll?: string;
|
|
19
23
|
saving_throw?: {
|
|
20
24
|
ability: string;
|
|
21
25
|
};
|