@archivist-gg/dnd5e 0.3.13 → 0.3.17
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 +5 -5
- package/dist/background/background.parser.js +4 -4
- package/dist/background/background.schema.js +3 -3
- package/dist/{chunk-ZMJQUZQH.js → chunk-2JSQE3DD.js} +11 -0
- package/dist/{chunk-Q6UOHCCT.js → chunk-2UDSN6VW.js} +1 -1
- package/dist/chunk-3LWMFYKS.js +57 -0
- package/dist/{chunk-MUIU7RZ3.js → chunk-3MGQFFNE.js} +1 -1
- package/dist/{chunk-T5GZBKIQ.js → chunk-3VZZDKRA.js} +114 -27
- package/dist/{chunk-BRGLDWUP.js → chunk-5MXFW4O3.js} +7 -3
- package/dist/{chunk-RQNJXADQ.js → chunk-6EI737IO.js} +1 -1
- package/dist/{chunk-EL6QPF6I.js → chunk-7ATNGKBS.js} +1 -1
- package/dist/{chunk-XY6X2APM.js → chunk-7Q2VPKCD.js} +17 -0
- package/dist/{chunk-4SLOJXJ4.js → chunk-7QN7XSAK.js} +1 -1
- package/dist/{chunk-MC5YJ4PB.js → chunk-AZRGFUSR.js} +1 -1
- package/dist/{chunk-HJQNK3J5.js → chunk-B3DP42OM.js} +1 -4
- package/dist/{chunk-JNNNBEUH.js → chunk-DOXSFYLH.js} +7 -2
- package/dist/{chunk-X7VZY4ON.js → chunk-FANQVQ3D.js} +2 -2
- package/dist/{chunk-PX25R3DK.js → chunk-G6PBI2BU.js} +1 -1
- package/dist/chunk-HTYMW5CH.js +228 -0
- package/dist/{chunk-VDPRBUU5.js → chunk-JCMUVZIK.js} +1 -1
- package/dist/{chunk-Q5XTEYHD.js → chunk-JSM6JFZR.js} +15 -8
- package/dist/chunk-KR6JF3BF.js +14 -0
- package/dist/{chunk-J53ERF6K.js → chunk-LF5AGJA4.js} +1 -1
- package/dist/{chunk-XJRNEQPD.js → chunk-MBX25B6D.js} +1 -1
- package/dist/{chunk-5KGV6TF7.js → chunk-OFCSP6MT.js} +1 -1
- package/dist/{chunk-QEO7LYTG.js → chunk-ONTGZR5T.js} +127 -71
- package/dist/{chunk-MWCCGPG3.js → chunk-OOSRUJBI.js} +3 -2
- package/dist/{chunk-LVX6TQ3R.js → chunk-PKX6TGRE.js} +2 -2
- package/dist/{chunk-QSBJ6NEM.js → chunk-PQZ4LM4Z.js} +1 -1
- package/dist/chunk-PXVNAY7T.js +84 -0
- package/dist/chunk-QH36K2PU.js +158 -0
- package/dist/{chunk-M2OWVAZG.js → chunk-QZSWN2KT.js} +1 -1
- package/dist/{chunk-6ZY3U6BQ.js → chunk-RYLXAYIQ.js} +1 -1
- package/dist/{chunk-UE6LKRXQ.js → chunk-T6QIF5XR.js} +16 -0
- package/dist/{chunk-4BZ47YJ4.js → chunk-TULQ4FFX.js} +32 -11
- package/dist/{chunk-PLOSP4XQ.js → chunk-UUBJCNQU.js} +11 -2
- package/dist/{chunk-DPM6V7YX.js → chunk-VRV3NNTA.js} +1 -1
- package/dist/{chunk-R2V5LN3I.js → chunk-Y5VVP73C.js} +1 -1
- package/dist/{chunk-FPGXFD2M.js → chunk-YD2VAHA6.js} +2 -2
- package/dist/{chunk-G7ED5H2G.js → chunk-YKL6SHRJ.js} +1 -1
- package/dist/class/class.codec.js +6 -6
- package/dist/class/class.parser.js +5 -5
- package/dist/class/class.schema.d.ts +8 -0
- package/dist/class/class.schema.js +4 -4
- package/dist/class/class.standard-array.d.ts +16 -0
- package/dist/class/class.standard-array.js +20 -0
- package/dist/class/class.types.d.ts +3 -0
- package/dist/dnd/amount-text.d.ts +38 -0
- package/dist/dnd/amount-text.js +13 -0
- package/dist/dnd/resource-words.d.ts +4 -0
- package/dist/dnd/resource-words.js +30 -0
- package/dist/feat/feat.codec.js +5 -5
- package/dist/feat/feat.parser.js +4 -4
- package/dist/feat/feat.schema.d.ts +25 -0
- package/dist/feat/feat.schema.js +3 -3
- package/dist/index.js +332 -70
- package/dist/monster/monster.parser.js +5 -5
- package/dist/monster/monster.schema.js +4 -4
- package/dist/optional-feature/optional-feature.codec.js +5 -4
- package/dist/optional-feature/optional-feature.parser.js +4 -3
- package/dist/optional-feature/optional-feature.schema.d.ts +26 -0
- package/dist/optional-feature/optional-feature.schema.js +3 -2
- package/dist/pc/pc.additional-spells.js +2 -2
- package/dist/pc/pc.amount-bindings.d.ts +32 -0
- package/dist/pc/pc.amount-bindings.js +23 -0
- package/dist/pc/pc.decision-engine.d.ts +3 -0
- package/dist/pc/pc.decision-engine.js +14 -13
- package/dist/pc/pc.entry-overrides.js +3 -3
- package/dist/pc/pc.equipment.js +6 -5
- package/dist/pc/pc.feature-effects.d.ts +12 -0
- package/dist/pc/pc.feature-effects.js +1 -1
- package/dist/pc/pc.infusions.d.ts +9 -1
- package/dist/pc/pc.infusions.js +3 -3
- package/dist/pc/pc.member-choices.d.ts +90 -0
- package/dist/pc/pc.member-choices.js +32 -0
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.d.ts +7 -0
- package/dist/pc/pc.pools.js +5 -3
- package/dist/pc/pc.proficiencies.js +13 -12
- package/dist/pc/pc.proficiency-query.js +6 -0
- package/dist/pc/pc.recalc.js +75 -58
- package/dist/pc/pc.resolver.d.ts +2 -1
- package/dist/pc/pc.resolver.js +13 -12
- package/dist/pc/pc.rest.js +4 -4
- package/dist/pc/pc.schema.d.ts +29 -2
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.types.d.ts +45 -2
- package/dist/pc/pc.weapon-grant.d.ts +15 -0
- package/dist/pc/pool-layout.d.ts +3 -9
- package/dist/pc/pool-layout.js +1 -3
- package/dist/pc/resource-equivalents.d.ts +44 -0
- package/dist/pc/spell-source.js +4 -9
- package/dist/race/race.codec.js +6 -6
- package/dist/race/race.parser.js +5 -5
- package/dist/race/race.schema.js +4 -4
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/feature-effect-schema.d.ts +25 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.js +3 -3
- package/dist/spell/spell.codec.js +2 -2
- package/dist/spell/spell.parser.d.ts +6 -1
- package/dist/spell/spell.parser.js +5 -3
- package/dist/spell/spell.types.d.ts +10 -0
- package/dist/subclass/subclass.codec.js +6 -6
- package/dist/subclass/subclass.parser.js +5 -5
- package/dist/subclass/subclass.schema.js +4 -4
- package/dist/types/choice.d.ts +5 -0
- package/dist/types/feature-effect.d.ts +6 -0
- package/dist/types/optional-feature.types.d.ts +5 -0
- package/dist/types/selection-pool.d.ts +2 -2
- package/package.json +1 -1
|
@@ -10,6 +10,23 @@ import {
|
|
|
10
10
|
expandToolPool,
|
|
11
11
|
toolCategoriesOf
|
|
12
12
|
} from "./chunk-H5PTKYXL.js";
|
|
13
|
+
import {
|
|
14
|
+
assembleEffectFeatures,
|
|
15
|
+
collectProficiencyEffectGrants
|
|
16
|
+
} from "./chunk-TULQ4FFX.js";
|
|
17
|
+
import {
|
|
18
|
+
ALL_LANGUAGES,
|
|
19
|
+
ALL_SKILL_SLUGS,
|
|
20
|
+
ALL_TOOLS
|
|
21
|
+
} from "./chunk-KU3YLF6D.js";
|
|
22
|
+
import {
|
|
23
|
+
featOfSite,
|
|
24
|
+
featPickSites,
|
|
25
|
+
isTargetChoice,
|
|
26
|
+
memberChoices,
|
|
27
|
+
poolMemberSites,
|
|
28
|
+
poolMemberSitesOf
|
|
29
|
+
} from "./chunk-HTYMW5CH.js";
|
|
13
30
|
import {
|
|
14
31
|
resolveFeatureResources,
|
|
15
32
|
resolveResourceIndex
|
|
@@ -21,25 +38,22 @@ import {
|
|
|
21
38
|
resolveSpellcasting
|
|
22
39
|
} from "./chunk-DPUJDOKV.js";
|
|
23
40
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
ALL_LANGUAGES,
|
|
29
|
-
ALL_SKILL_SLUGS,
|
|
30
|
-
ALL_TOOLS
|
|
31
|
-
} from "./chunk-KU3YLF6D.js";
|
|
41
|
+
convertibleLegacyAsi,
|
|
42
|
+
flattenAsiOrFeat,
|
|
43
|
+
resolveLegacyAsiFeat
|
|
44
|
+
} from "./chunk-LBEXLN6I.js";
|
|
32
45
|
import {
|
|
33
46
|
humanizeProficiency,
|
|
34
47
|
proficiencyLabel,
|
|
35
48
|
toProfSlug
|
|
36
49
|
} from "./chunk-RLGQ5PZZ.js";
|
|
37
50
|
import {
|
|
51
|
+
bindFeatureConsumers,
|
|
38
52
|
buildInfusionContext,
|
|
39
53
|
resolveAllPools,
|
|
40
54
|
resolveOptionRows,
|
|
41
55
|
strandedPicks
|
|
42
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-3VZZDKRA.js";
|
|
43
57
|
import {
|
|
44
58
|
countColumnsFor,
|
|
45
59
|
readTableColumn
|
|
@@ -49,33 +63,28 @@ import {
|
|
|
49
63
|
} from "./chunk-YHYTW5QA.js";
|
|
50
64
|
import {
|
|
51
65
|
collectAdditionalSpells
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import {
|
|
54
|
-
convertibleLegacyAsi,
|
|
55
|
-
flattenAsiOrFeat,
|
|
56
|
-
resolveLegacyAsiFeat
|
|
57
|
-
} from "./chunk-LBEXLN6I.js";
|
|
66
|
+
} from "./chunk-VRV3NNTA.js";
|
|
58
67
|
import {
|
|
59
68
|
isItemEntity,
|
|
60
69
|
resolveEntityForEntry
|
|
61
70
|
} from "./chunk-LHZXYFBU.js";
|
|
62
|
-
import {
|
|
63
|
-
warnOnce
|
|
64
|
-
} from "./chunk-LVQLWRCU.js";
|
|
65
|
-
import {
|
|
66
|
-
bareEntitySlug,
|
|
67
|
-
wikilinkTailSlug
|
|
68
|
-
} from "./chunk-ZCTUYGNV.js";
|
|
69
71
|
import {
|
|
70
72
|
FEATURE_TYPE_FOR_CATEGORY,
|
|
71
73
|
featProgressionCategory
|
|
72
74
|
} from "./chunk-YBLDE5CG.js";
|
|
75
|
+
import {
|
|
76
|
+
warnOnce
|
|
77
|
+
} from "./chunk-LVQLWRCU.js";
|
|
73
78
|
import {
|
|
74
79
|
isValidMaxFormula
|
|
75
80
|
} from "./chunk-EVMUJYUD.js";
|
|
81
|
+
import {
|
|
82
|
+
bareEntitySlug,
|
|
83
|
+
wikilinkTailSlug
|
|
84
|
+
} from "./chunk-ZCTUYGNV.js";
|
|
76
85
|
import {
|
|
77
86
|
mirrorSpellShapes
|
|
78
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-7Q2VPKCD.js";
|
|
79
88
|
import {
|
|
80
89
|
ABILITY_KEYS
|
|
81
90
|
} from "./chunk-WELIKLZF.js";
|
|
@@ -205,6 +214,7 @@ function matchesFilter(e, where, ownerBare) {
|
|
|
205
214
|
if (where.list && !((_a = d.classes) != null ? _a : []).includes(where.list)) return false;
|
|
206
215
|
if (where.level !== void 0 && ((_b = d.level) != null ? _b : 0) !== where.level) return false;
|
|
207
216
|
if (where.edition && d.edition !== where.edition) return false;
|
|
217
|
+
if (where.ritual && d.ritual !== true) return false;
|
|
208
218
|
if (where.weapon_category) {
|
|
209
219
|
const cat = ((_c = d.category) != null ? _c : "").toLowerCase();
|
|
210
220
|
if (!cat.startsWith(`${where.weapon_category}-`) && cat !== where.weapon_category) return false;
|
|
@@ -527,8 +537,13 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
527
537
|
const originRead = (ns) => (id) => oc[`${ns}:${id}`];
|
|
528
538
|
const stripRef = (ref) => ref.replace(/^\[\[/, "").replace(/\]\]$/, "");
|
|
529
539
|
const featBySlug = new Map(((_b = resolved.feats) != null ? _b : []).map((f) => [f.slug, f]));
|
|
530
|
-
|
|
540
|
+
const memberSites = poolMemberSitesOf(resolved);
|
|
541
|
+
const featSites = featPickSites(resolved.classes, memberSites, (ci) => {
|
|
531
542
|
var _a2, _b2, _c2, _d;
|
|
543
|
+
return (_d = (_c2 = (_b2 = (_a2 = resolved.classes) == null ? void 0 : _a2[ci]) == null ? void 0 : _b2.entity) == null ? void 0 : _c2.slug) != null ? _d : null;
|
|
544
|
+
});
|
|
545
|
+
resolved.classes.forEach((c, i) => {
|
|
546
|
+
var _a2, _b2, _c2, _d, _e;
|
|
532
547
|
if (!c.entity) return;
|
|
533
548
|
const entity = c.entity;
|
|
534
549
|
const readAt = (lvl) => (id) => {
|
|
@@ -553,14 +568,13 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
553
568
|
for (const copy of (_c2 = rf.foldedFrom) != null ? _c2 : []) walk(copy.choices, readAt(copy.level));
|
|
554
569
|
walk(rf.feature.choices, readAt(rf.source.level));
|
|
555
570
|
}
|
|
556
|
-
for (const
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
if (!block || typeof featRef !== "string") continue;
|
|
560
|
-
const feat = featBySlug.get(stripRef(featRef));
|
|
571
|
+
for (const site of featSites) {
|
|
572
|
+
if (site.classIndex !== i) continue;
|
|
573
|
+
const feat = (_e = featBySlug.get(stripRef(site.slug))) != null ? _e : featOfSite(site, (_d = resolved.feats) != null ? _d : []);
|
|
561
574
|
if (!feat) continue;
|
|
562
|
-
walk(feat.choices,
|
|
575
|
+
walk(feat.choices, site.read);
|
|
563
576
|
}
|
|
577
|
+
for (const site of memberSites) if (site.classIndex === i) walk(site.choices, site.read);
|
|
564
578
|
});
|
|
565
579
|
if (resolved.race) {
|
|
566
580
|
walk(resolved.race.choices, originRead("race"));
|
|
@@ -961,6 +975,28 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
961
975
|
});
|
|
962
976
|
}
|
|
963
977
|
for (const o of item.options) if (strandedSlugs.has(o.value)) o.stranded = true;
|
|
978
|
+
const memberChildren = [];
|
|
979
|
+
for (const entry of pool.selected) {
|
|
980
|
+
for (const ch of memberChoices(entry.entity)) {
|
|
981
|
+
const child = buildItem(
|
|
982
|
+
ch,
|
|
983
|
+
{ kind: "class", slug: entity.slug, level: pool.anchorLevel },
|
|
984
|
+
pool.anchorLevel,
|
|
985
|
+
entry.entity.name,
|
|
986
|
+
readAt(pool.anchorLevel),
|
|
987
|
+
ctx,
|
|
988
|
+
ownerBare,
|
|
989
|
+
effective,
|
|
990
|
+
{ keyPrefix: `${pool.id}:${entry.key}:` }
|
|
991
|
+
);
|
|
992
|
+
child.parentLabel = entry.entity.name;
|
|
993
|
+
memberChildren.push(child);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
if (memberChildren.length) {
|
|
997
|
+
item.children = memberChildren;
|
|
998
|
+
if (item.status === "resolved" && memberChildren.some((c2) => c2.status !== "resolved")) item.status = "partial";
|
|
999
|
+
}
|
|
964
1000
|
push(pool.anchorLevel, item);
|
|
965
1001
|
}
|
|
966
1002
|
for (const entry of featProgressions) {
|
|
@@ -1168,7 +1204,7 @@ var PCResolver = class {
|
|
|
1168
1204
|
return this.entities;
|
|
1169
1205
|
}
|
|
1170
1206
|
resolve(character) {
|
|
1171
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
1207
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1172
1208
|
const warnings = [];
|
|
1173
1209
|
const lookup = (rawRef, type) => {
|
|
1174
1210
|
const slug = stripSlug(rawRef);
|
|
@@ -1189,14 +1225,19 @@ var PCResolver = class {
|
|
|
1189
1225
|
subclass: lookup(c.subclass, "subclass"),
|
|
1190
1226
|
choices: c.choices
|
|
1191
1227
|
}));
|
|
1228
|
+
const memberSites = poolMemberSites(classes, this.entities);
|
|
1229
|
+
const classSlugOf = (i) => {
|
|
1230
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
1231
|
+
return (_e2 = (_b2 = (_a2 = classes[i]) == null ? void 0 : _a2.entity) == null ? void 0 : _b2.slug) != null ? _e2 : stripSlug((_d2 = (_c2 = character.class[i]) == null ? void 0 : _c2.name) != null ? _d2 : null);
|
|
1232
|
+
};
|
|
1233
|
+
const featSites = featPickSites(character.class, memberSites, classSlugOf);
|
|
1192
1234
|
const feats = [];
|
|
1193
1235
|
const featVia = /* @__PURE__ */ new Map();
|
|
1194
|
-
for (const
|
|
1195
|
-
const f = lookup(`[[${
|
|
1236
|
+
for (const site of featSites) {
|
|
1237
|
+
const f = lookup(`[[${site.slug}]]`, "feat");
|
|
1196
1238
|
if (!f) continue;
|
|
1197
|
-
feats.push(f);
|
|
1198
|
-
|
|
1199
|
-
if (classSlug && pick.level !== null && !featVia.has(f.slug)) featVia.set(f.slug, { kind: "class", slug: classSlug, level: pick.level });
|
|
1239
|
+
if (!feats.some((x) => x.slug === f.slug)) feats.push(f);
|
|
1240
|
+
if (site.via && !featVia.has(f.slug)) featVia.set(f.slug, site.via);
|
|
1200
1241
|
}
|
|
1201
1242
|
const originFeat = (background == null ? void 0 : background.origin_feat) ? resolveOriginFeat(this.entities, background.origin_feat, background.slug) : null;
|
|
1202
1243
|
const originFeatSlug = originFeat == null ? void 0 : originFeat.feat.slug;
|
|
@@ -1208,7 +1249,7 @@ var PCResolver = class {
|
|
|
1208
1249
|
}
|
|
1209
1250
|
const totalLevel = classes.reduce((sum, c) => sum + c.level, 0);
|
|
1210
1251
|
const features = collectResolvedFeatures(race, classes, background, feats, featVia);
|
|
1211
|
-
const extraFeatures = collectChosenGrantedFeatures(character, classes, this.entities, race, background);
|
|
1252
|
+
const extraFeatures = collectChosenGrantedFeatures(character, classes, this.entities, race, background, memberSites);
|
|
1212
1253
|
features.push(...extraFeatures);
|
|
1213
1254
|
features.push(...collectAdditionalFeatures(character, this.entities, warnings));
|
|
1214
1255
|
const casters = [];
|
|
@@ -1218,7 +1259,7 @@ var PCResolver = class {
|
|
|
1218
1259
|
if (profile && classSlug != null) casters.push({ classSlug, spellList: profile.spellList });
|
|
1219
1260
|
});
|
|
1220
1261
|
const spells = [];
|
|
1221
|
-
for (const raw of (
|
|
1262
|
+
for (const raw of (_a = character.spells.known) != null ? _a : []) {
|
|
1222
1263
|
const n = normalizeKnownSpell(raw);
|
|
1223
1264
|
const reg = this.entities.getByTypeAndSlug("spell", n.slug);
|
|
1224
1265
|
if (!reg) {
|
|
@@ -1226,34 +1267,45 @@ var PCResolver = class {
|
|
|
1226
1267
|
continue;
|
|
1227
1268
|
}
|
|
1228
1269
|
const entity = mirrorSpellShapes(reg.data);
|
|
1229
|
-
const isCantrip = ((
|
|
1230
|
-
const classSlug = (
|
|
1231
|
-
const prep = isCantrip || n.alwaysPrepared ? true : (
|
|
1270
|
+
const isCantrip = ((_b = entity.level) != null ? _b : 0) === 0;
|
|
1271
|
+
const classSlug = (_c = n.classSlug) != null ? _c : attributeUnclassedSpell(entity.classes, casters, this.entities);
|
|
1272
|
+
const prep = isCantrip || n.alwaysPrepared ? true : (_d = n.preparedFlag) != null ? _d : false;
|
|
1232
1273
|
spells.push({ entity, slug: n.slug, classSlug, source: n.source, prepared: prep, alwaysPrepared: n.alwaysPrepared, persisted: true });
|
|
1233
1274
|
}
|
|
1234
|
-
const oc = (
|
|
1275
|
+
const oc = (_e = character.origin_choices) != null ? _e : {};
|
|
1235
1276
|
if (originFeat) {
|
|
1236
1277
|
const read = (childId) => oc[`background:feat:${childId}`];
|
|
1237
1278
|
spells.push(...collectFeatGrantedSpells(originFeat.feat, read, this.entities, warnings));
|
|
1238
1279
|
}
|
|
1239
|
-
for (const
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1280
|
+
for (const site of featSites) {
|
|
1281
|
+
const reg = this.entities.getByTypeAndSlug("feat", site.slug);
|
|
1282
|
+
if (!reg) continue;
|
|
1283
|
+
const feat = reg.data;
|
|
1284
|
+
spells.push(...collectFeatGrantedSpells(feat, site.read, this.entities, warnings));
|
|
1285
|
+
}
|
|
1286
|
+
for (const site of memberSites) {
|
|
1287
|
+
const classSlug = stripSlug((_g = (_f = character.class[site.classIndex]) == null ? void 0 : _f.name) != null ? _g : null);
|
|
1288
|
+
for (const ch of site.choices) {
|
|
1289
|
+
if (ch.kind !== "select-entity" || ch.entity_type !== "spell" || isTargetChoice(ch)) continue;
|
|
1290
|
+
const v = site.read(ch.id);
|
|
1291
|
+
for (const ref of Array.isArray(v) ? v : typeof v === "string" ? [v] : []) {
|
|
1292
|
+
const slug = typeof ref === "string" ? stripSlug(ref) : null;
|
|
1293
|
+
if (!slug) continue;
|
|
1294
|
+
const reg = this.entities.getByTypeAndSlug("spell", slug);
|
|
1295
|
+
if (!reg) {
|
|
1296
|
+
warnings.push(`Spell [[${slug}]] not found in compendium.`);
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
const entity = mirrorSpellShapes(reg.data);
|
|
1300
|
+
spells.push({ entity, slug, classSlug, source: "class", prepared: true, alwaysPrepared: true });
|
|
1301
|
+
}
|
|
1250
1302
|
}
|
|
1251
1303
|
}
|
|
1252
|
-
const ownSpellcastingAbility = (
|
|
1304
|
+
const ownSpellcastingAbility = (_h = classes.map((c) => {
|
|
1253
1305
|
if (!c.entity) return null;
|
|
1254
1306
|
const p = resolveSpellcasting(c);
|
|
1255
1307
|
return p ? effectiveSpellcastingAbility(c.entity.slug, p.ability, character.overrides) : null;
|
|
1256
|
-
}).find((a) => a != null)) != null ?
|
|
1308
|
+
}).find((a) => a != null)) != null ? _h : null;
|
|
1257
1309
|
spells.push(...collectItemGrantedSpells(character, ownSpellcastingAbility, this.entities, warnings));
|
|
1258
1310
|
spells.push(...collectAdditionalSpells({
|
|
1259
1311
|
race,
|
|
@@ -1304,6 +1356,7 @@ var PCResolver = class {
|
|
|
1304
1356
|
};
|
|
1305
1357
|
resolvedCharacter.pools = resolveAllPools(resolvedCharacter, this.entities, featureResources);
|
|
1306
1358
|
resolvedCharacter.resources = resolveResourceIndex(resolvedCharacter);
|
|
1359
|
+
resolvedCharacter.features = bindFeatureConsumers(resolvedCharacter.features, resolvedCharacter.resources, classes);
|
|
1307
1360
|
const infusions = buildInfusionContext(character, resolvedCharacter, this.entities);
|
|
1308
1361
|
if (infusions) resolvedCharacter.infusions = infusions;
|
|
1309
1362
|
return { character: resolvedCharacter, warnings };
|
|
@@ -1324,16 +1377,9 @@ function collectChosenWeaponMasteries(character) {
|
|
|
1324
1377
|
}
|
|
1325
1378
|
function collectFeatPicks(character) {
|
|
1326
1379
|
const picks = /* @__PURE__ */ new Map();
|
|
1327
|
-
character.class
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
if (typeof feat === "string") {
|
|
1331
|
-
const s = stripSlug(feat);
|
|
1332
|
-
const level = /^\d+$/.test(lvl) ? Number(lvl) : null;
|
|
1333
|
-
if (s && !picks.has(s)) picks.set(s, { slug: s, classIndex, level });
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1380
|
+
for (const site of featPickSites(character.class, [], () => null)) {
|
|
1381
|
+
if (!picks.has(site.slug)) picks.set(site.slug, { slug: site.slug, classIndex: site.classIndex, level: site.level });
|
|
1382
|
+
}
|
|
1337
1383
|
return [...picks.values()];
|
|
1338
1384
|
}
|
|
1339
1385
|
function collectFeatGrantedSpells(feat, read, entities, warnings) {
|
|
@@ -1410,11 +1456,21 @@ function collectSpellPickSlugs(choices, read, out) {
|
|
|
1410
1456
|
}
|
|
1411
1457
|
}
|
|
1412
1458
|
}
|
|
1413
|
-
function collectChosenGrantedFeatures(character, classes, registry, race = null, background = null) {
|
|
1414
|
-
var _a, _b;
|
|
1459
|
+
function collectChosenGrantedFeatures(character, classes, registry, race = null, background = null, memberSites = []) {
|
|
1460
|
+
var _a, _b, _c, _d;
|
|
1415
1461
|
const out = [];
|
|
1462
|
+
for (const site of memberSites) {
|
|
1463
|
+
const classSlug = (_b = (_a = classes[site.classIndex]) == null ? void 0 : _a.entity) == null ? void 0 : _b.slug;
|
|
1464
|
+
if (!classSlug) continue;
|
|
1465
|
+
const at = {};
|
|
1466
|
+
const grants = site.choices.filter((ch) => !isTargetChoice(ch));
|
|
1467
|
+
for (const ch of grants) at[ch.id] = site.read(ch.id);
|
|
1468
|
+
walkChoiceGrants(grants, at, (granted, suppress) => {
|
|
1469
|
+
out.push({ feature: granted, source: { kind: "class", slug: classSlug, level: site.level }, ...suppress ? { renderSuppressed: true } : {} });
|
|
1470
|
+
}, registry);
|
|
1471
|
+
}
|
|
1416
1472
|
classes.forEach((c, i) => {
|
|
1417
|
-
var _a2, _b2,
|
|
1473
|
+
var _a2, _b2, _c2, _d2;
|
|
1418
1474
|
if (!c.entity) return;
|
|
1419
1475
|
const entity = c.entity;
|
|
1420
1476
|
const entry = character.class[i];
|
|
@@ -1423,7 +1479,7 @@ function collectChosenGrantedFeatures(character, classes, registry, race = null,
|
|
|
1423
1479
|
const lvl = Number(lvlStr);
|
|
1424
1480
|
if (!Number.isFinite(lvl) || lvl > entry.level) continue;
|
|
1425
1481
|
const features = (_b2 = ((_a2 = entity.features_by_level) != null ? _a2 : {})[lvl]) != null ? _b2 : [];
|
|
1426
|
-
const subFeatures = c.subclass ? (
|
|
1482
|
+
const subFeatures = c.subclass ? (_d2 = ((_c2 = c.subclass.features_by_level) != null ? _c2 : {})[lvl]) != null ? _d2 : [] : [];
|
|
1427
1483
|
for (const feature of [...features, ...subFeatures]) {
|
|
1428
1484
|
walkChoiceGrants(feature.choices, atLevel, (granted, suppress) => {
|
|
1429
1485
|
out.push({
|
|
@@ -1435,7 +1491,7 @@ function collectChosenGrantedFeatures(character, classes, registry, race = null,
|
|
|
1435
1491
|
}
|
|
1436
1492
|
}
|
|
1437
1493
|
});
|
|
1438
|
-
const oc = (
|
|
1494
|
+
const oc = (_c = character.origin_choices) != null ? _c : {};
|
|
1439
1495
|
const originAt = (ns) => {
|
|
1440
1496
|
const at = {};
|
|
1441
1497
|
for (const [key, val] of Object.entries(oc)) {
|
|
@@ -1453,7 +1509,7 @@ function collectChosenGrantedFeatures(character, classes, registry, race = null,
|
|
|
1453
1509
|
});
|
|
1454
1510
|
};
|
|
1455
1511
|
walkChoiceGrants(race.choices, atRace, emitRace, registry);
|
|
1456
|
-
for (const trait of (
|
|
1512
|
+
for (const trait of (_d = race.traits) != null ? _d : []) {
|
|
1457
1513
|
walkChoiceGrants(trait.choices, atRace, emitRace, registry);
|
|
1458
1514
|
}
|
|
1459
1515
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSpell
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7Q2VPKCD.js";
|
|
4
4
|
|
|
5
5
|
// src/spell/spell.codec.ts
|
|
6
6
|
import yaml from "js-yaml";
|
|
@@ -9,7 +9,8 @@ var spellCodec = {
|
|
|
9
9
|
return parseSpell(doc.body);
|
|
10
10
|
},
|
|
11
11
|
serialize(spell) {
|
|
12
|
-
|
|
12
|
+
const { material: _material, ...doc } = spell;
|
|
13
|
+
return yaml.dump(doc, { lineWidth: -1, sortKeys: false });
|
|
13
14
|
}
|
|
14
15
|
};
|
|
15
16
|
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-ZJXSXVFP.js";
|
|
5
5
|
import {
|
|
6
6
|
choiceSchema
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5MXFW4O3.js";
|
|
8
8
|
import {
|
|
9
9
|
featureEffectSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2JSQE3DD.js";
|
|
11
11
|
import {
|
|
12
12
|
additionalSpellsEntrySchema,
|
|
13
13
|
imageField,
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
spellSource
|
|
3
|
+
} from "./chunk-KR6JF3BF.js";
|
|
4
|
+
import {
|
|
5
|
+
resourceLevelFor
|
|
6
|
+
} from "./chunk-KSTV7J2U.js";
|
|
7
|
+
import {
|
|
8
|
+
baseClassName
|
|
9
|
+
} from "./chunk-VTTA2ALZ.js";
|
|
10
|
+
|
|
11
|
+
// src/pc/pc.amount-bindings.ts
|
|
12
|
+
function ownerClassSlug(source, resolved) {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
if (!source) return null;
|
|
15
|
+
if (source.kind === "class") return source.slug;
|
|
16
|
+
if (source.kind === "subclass") return (_c = (_b = (_a = resolved.classes.find((c) => {
|
|
17
|
+
var _a2;
|
|
18
|
+
return ((_a2 = c.subclass) == null ? void 0 : _a2.slug) === source.slug;
|
|
19
|
+
})) == null ? void 0 : _a.entity) == null ? void 0 : _b.slug) != null ? _c : null;
|
|
20
|
+
if (source.kind === "feat" && source.via) {
|
|
21
|
+
if (source.via.kind === "class") return source.via.slug;
|
|
22
|
+
if (source.via.kind === "pool") return source.via.classSlug;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function casterRow(classSlug, derived) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
const rows = (_a = derived.spellcastingClasses) != null ? _a : [];
|
|
29
|
+
const own = classSlug ? rows.find((c) => baseClassName(c.classSlug) === baseClassName(classSlug)) : void 0;
|
|
30
|
+
return (_b = own != null ? own : rows[0]) != null ? _b : null;
|
|
31
|
+
}
|
|
32
|
+
function amountBindingsFor(owner, resolved, derived) {
|
|
33
|
+
const classSlug = ownerClassSlug(owner, resolved);
|
|
34
|
+
const classSource = classSlug ? { kind: "class", slug: classSlug, level: 0 } : owner;
|
|
35
|
+
const classLevel = classSource ? resourceLevelFor(classSource, resolved) : resolved.totalLevel;
|
|
36
|
+
const row = casterRow(classSlug, derived);
|
|
37
|
+
return {
|
|
38
|
+
level: resolved.totalLevel,
|
|
39
|
+
class_level: classLevel,
|
|
40
|
+
prof: derived.proficiencyBonus,
|
|
41
|
+
str_mod: derived.mods.str,
|
|
42
|
+
dex_mod: derived.mods.dex,
|
|
43
|
+
con_mod: derived.mods.con,
|
|
44
|
+
int_mod: derived.mods.int,
|
|
45
|
+
wis_mod: derived.mods.wis,
|
|
46
|
+
cha_mod: derived.mods.cha,
|
|
47
|
+
columns: {},
|
|
48
|
+
...row ? { spell_mod: derived.mods[row.ability], spell_dc: row.saveDC } : {}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function spellcastingFor(spell, derived) {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
if ((spellSource(spell).ownAbility || spell.classSlug == null) && spell.ability) {
|
|
54
|
+
const own = (_a = derived.abilitySpellcasting) == null ? void 0 : _a[spell.ability];
|
|
55
|
+
if (own) return { ability: spell.ability, saveDC: own.saveDC, attackBonus: own.attackBonus };
|
|
56
|
+
}
|
|
57
|
+
const row = casterRow((_b = spell.classSlug) != null ? _b : null, derived);
|
|
58
|
+
return row ? { ability: row.ability, saveDC: row.saveDC, attackBonus: row.attackBonus } : null;
|
|
59
|
+
}
|
|
60
|
+
function spellAmountBindings(spell, resolved, derived) {
|
|
61
|
+
const cast = spellcastingFor(spell, derived);
|
|
62
|
+
const base = amountBindingsFor(spell.classSlug ? { kind: "class", slug: spell.classSlug, level: 0 } : void 0, resolved, derived);
|
|
63
|
+
const out = { ...base };
|
|
64
|
+
delete out.spell_mod;
|
|
65
|
+
delete out.spell_dc;
|
|
66
|
+
return cast ? { ...out, spell_mod: derived.mods[cast.ability], spell_dc: cast.saveDC } : out;
|
|
67
|
+
}
|
|
68
|
+
function spellRollBonus(spell) {
|
|
69
|
+
var _a;
|
|
70
|
+
const roll = (_a = spell.damage_roll) == null ? void 0 : _a.trim();
|
|
71
|
+
const text = spell.description;
|
|
72
|
+
if (!roll || !text) return null;
|
|
73
|
+
const esc = roll.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
74
|
+
const re = new RegExp(`(?<![\\w])${esc}\`?\\s*(?:plus|\\+)\\s*your\\s+spellcasting\\s+(?:ability\\s+)?modifier`, "i");
|
|
75
|
+
return re.test(text) ? "{spell_mod}" : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
ownerClassSlug,
|
|
80
|
+
amountBindingsFor,
|
|
81
|
+
spellcastingFor,
|
|
82
|
+
spellAmountBindings,
|
|
83
|
+
spellRollBonus
|
|
84
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evaluateMaxFormula,
|
|
3
|
+
isValidMaxFormula
|
|
4
|
+
} from "./chunk-EVMUJYUD.js";
|
|
5
|
+
|
|
6
|
+
// src/dnd/amount-text.ts
|
|
7
|
+
var ABILITY_WORD = {
|
|
8
|
+
strength: "str",
|
|
9
|
+
dexterity: "dex",
|
|
10
|
+
constitution: "con",
|
|
11
|
+
intelligence: "int",
|
|
12
|
+
wisdom: "wis",
|
|
13
|
+
charisma: "cha",
|
|
14
|
+
str: "str",
|
|
15
|
+
dex: "dex",
|
|
16
|
+
con: "con",
|
|
17
|
+
int: "int",
|
|
18
|
+
wis: "wis",
|
|
19
|
+
cha: "cha"
|
|
20
|
+
};
|
|
21
|
+
var ABILITY_RE = "(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)";
|
|
22
|
+
var CLASS_RE = "(Artificer|Barbarian|Bard|Cleric|Druid|Fighter|Monk|Paladin|Ranger|Rogue|Sorcerer|Warlock|Wizard)";
|
|
23
|
+
var TOKEN_ALIAS = {
|
|
24
|
+
prof_bonus: "prof",
|
|
25
|
+
proficiency_bonus: "prof",
|
|
26
|
+
spellcasting_mod: "spell_mod",
|
|
27
|
+
spell_save_dc: "spell_dc"
|
|
28
|
+
};
|
|
29
|
+
var IDENT_LABEL = {
|
|
30
|
+
level: "level",
|
|
31
|
+
class_level: "class level",
|
|
32
|
+
prof: "PB",
|
|
33
|
+
str_mod: "STR mod",
|
|
34
|
+
dex_mod: "DEX mod",
|
|
35
|
+
con_mod: "CON mod",
|
|
36
|
+
int_mod: "INT mod",
|
|
37
|
+
wis_mod: "WIS mod",
|
|
38
|
+
cha_mod: "CHA mod",
|
|
39
|
+
spell_mod: "spellcasting mod",
|
|
40
|
+
spell_dc: "spell save DC"
|
|
41
|
+
};
|
|
42
|
+
var abilityToken = (word) => `{${ABILITY_WORD[word.toLowerCase()]}_mod}`;
|
|
43
|
+
var PHRASES = [
|
|
44
|
+
// Save DCs: "your spell save DC", "your sorcerer spell save DC", "the spell save DC from this class's Spellcasting feature".
|
|
45
|
+
[/\b(?:your|the)\s+(?:[a-z]+\s+)?spell save DC(?:\s+from this class's Spellcasting feature)?/gi, "{spell_dc}"],
|
|
46
|
+
// "8 plus your Wisdom modifier and Proficiency Bonus" (2024) / the 2014 order is caught by the rows below.
|
|
47
|
+
[
|
|
48
|
+
new RegExp(`\\b8 plus your ${ABILITY_RE} modifier and (?:your )?Proficiency Bonus`, "gi"),
|
|
49
|
+
(_m, a) => `8 + ${abilityToken(a)} + {prof}`
|
|
50
|
+
],
|
|
51
|
+
// The spellcasting modifier, in every spelling the notes carry.
|
|
52
|
+
[/\b(?:your\s+)?spellcasting ability modifier\b/gi, "{spell_mod}"],
|
|
53
|
+
[/\b(?:your\s+)?spellcasting modifier\b/gi, "{spell_mod}"],
|
|
54
|
+
[/\b(?:your\s+)?spell(?:casting)? mod\b/gi, "{spell_mod}"],
|
|
55
|
+
// An ability modifier: "your Wisdom modifier", "Intelligence modifier", "WIS mod".
|
|
56
|
+
[new RegExp(`\\b(?:your\\s+)?${ABILITY_RE} modifier\\b`, "gi"), (_m, a) => abilityToken(a)],
|
|
57
|
+
[/\b(STR|DEX|CON|INT|WIS|CHA) mod(?:ifier)?\b/g, (_m, a) => abilityToken(a)],
|
|
58
|
+
// Class level: "half your Warlock level", "your fighter level"; the character's level.
|
|
59
|
+
[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? up\\))`, "gi"), "ceil({class_level} / 2)"],
|
|
60
|
+
[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? down\\))?`, "gi"), "floor({class_level} / 2)"],
|
|
61
|
+
[/\bhalf your level in this class(?:\s*\(round(?:ed)? up\))/gi, "ceil({class_level} / 2)"],
|
|
62
|
+
[/\bhalf your level in this class(?:\s*\(round(?:ed)? down\))?/gi, "floor({class_level} / 2)"],
|
|
63
|
+
[new RegExp(`\\byour ${CLASS_RE} level\\b`, "gi"), "{class_level}"],
|
|
64
|
+
[/\byour level in this class\b/gi, "{class_level}"],
|
|
65
|
+
[/\byour (?:character )?level\b/gi, "{level}"],
|
|
66
|
+
// Proficiency bonus.
|
|
67
|
+
[/\b(?:your\s+)?proficiency bonus\b/gi, "{prof}"],
|
|
68
|
+
[/\bPB\b/g, "{prof}"]
|
|
69
|
+
];
|
|
70
|
+
function normalizeAmountPhrases(text) {
|
|
71
|
+
let out = text;
|
|
72
|
+
for (const [re, to] of PHRASES) out = out.replace(re, to);
|
|
73
|
+
if (out === text) return text;
|
|
74
|
+
out = out.replace(/\s+plus\s+/gi, " + ").replace(/\s+minus\s+/gi, " - ").replace(/\btwice (\{[a-z_]+\})/gi, "2 * $1");
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
var TRAILING_MIN = /\s*\(minimum(?: bonus)? of \+?(\d+)[^)]*\)\s*$/i;
|
|
78
|
+
var DICE = /^\d*d\d+$/i;
|
|
79
|
+
function tidySigns(s) {
|
|
80
|
+
return s.replace(/\+\s*-\s*/g, "- ").replace(/-\s*-\s*/g, "+ ");
|
|
81
|
+
}
|
|
82
|
+
function foldDice(expr) {
|
|
83
|
+
const parts = expr.replace(/\s+/g, "").match(/[+-]?[^+-]+/g);
|
|
84
|
+
if (!parts) return null;
|
|
85
|
+
const dice = [];
|
|
86
|
+
let sum = 0;
|
|
87
|
+
for (const raw of parts) {
|
|
88
|
+
const sign = raw.startsWith("-") ? -1 : 1;
|
|
89
|
+
const body = raw.replace(/^[+-]/, "");
|
|
90
|
+
if (DICE.test(body)) {
|
|
91
|
+
if (sign < 0) return null;
|
|
92
|
+
dice.push(body.toLowerCase());
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (!isValidMaxFormula(body)) return null;
|
|
96
|
+
sum += sign * evaluateMaxFormula(body, ZERO_BINDINGS);
|
|
97
|
+
}
|
|
98
|
+
if (dice.length === 0) return null;
|
|
99
|
+
const n = Math.trunc(sum);
|
|
100
|
+
return `${dice.join("+")}${n > 0 ? `+${n}` : n < 0 ? `${n}` : ""}`;
|
|
101
|
+
}
|
|
102
|
+
var ZERO_BINDINGS = {
|
|
103
|
+
level: 0,
|
|
104
|
+
class_level: 0,
|
|
105
|
+
prof: 0,
|
|
106
|
+
str_mod: 0,
|
|
107
|
+
dex_mod: 0,
|
|
108
|
+
con_mod: 0,
|
|
109
|
+
int_mod: 0,
|
|
110
|
+
wis_mod: 0,
|
|
111
|
+
cha_mod: 0,
|
|
112
|
+
columns: {}
|
|
113
|
+
};
|
|
114
|
+
function resolveAmountText(text, b) {
|
|
115
|
+
const normalized = normalizeAmountPhrases(text);
|
|
116
|
+
if (!normalized.includes("{")) return text;
|
|
117
|
+
const values = b;
|
|
118
|
+
let unbound = false;
|
|
119
|
+
const substitute = (numeric2) => normalized.replace(/\{([a-z_]+)\}/g, (_m, raw) => {
|
|
120
|
+
var _a, _b;
|
|
121
|
+
const id = (_a = TOKEN_ALIAS[raw]) != null ? _a : raw;
|
|
122
|
+
const v = values[id];
|
|
123
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
124
|
+
unbound = true;
|
|
125
|
+
return (_b = IDENT_LABEL[id]) != null ? _b : raw;
|
|
126
|
+
}
|
|
127
|
+
return numeric2 && v < 0 ? `(0 - ${-v})` : String(v);
|
|
128
|
+
});
|
|
129
|
+
const display = tidySigns(substitute(false));
|
|
130
|
+
if (unbound) return text.includes("{") ? display : text;
|
|
131
|
+
const min = TRAILING_MIN.exec(display);
|
|
132
|
+
const minText = min ? display.slice(min.index) : "";
|
|
133
|
+
const numeric = substitute(true);
|
|
134
|
+
const numericCore = numeric.replace(TRAILING_MIN, "");
|
|
135
|
+
if (isValidMaxFormula(numericCore)) {
|
|
136
|
+
const v = evaluateMaxFormula(numericCore, ZERO_BINDINGS);
|
|
137
|
+
return String(Math.trunc(min ? Math.max(Number(min[1]), v) : v));
|
|
138
|
+
}
|
|
139
|
+
const roll = foldDice(min ? display.slice(0, min.index) : display);
|
|
140
|
+
if (roll) return `${roll}${minText}`;
|
|
141
|
+
if (/\b(?:floor|ceil|max|min)\(/.test(display)) return text;
|
|
142
|
+
return display;
|
|
143
|
+
}
|
|
144
|
+
function diceRollOf(resolved) {
|
|
145
|
+
var _a, _b;
|
|
146
|
+
return (_b = (_a = diceRollPrefix(resolved)) == null ? void 0 : _a.notation) != null ? _b : null;
|
|
147
|
+
}
|
|
148
|
+
function diceRollPrefix(text) {
|
|
149
|
+
const m = /^(\d*d\d+(?:\s*[+-]\s*\d+)*)(?=\s|$)/i.exec(text);
|
|
150
|
+
return m ? { raw: m[1], notation: m[1].replace(/\s+/g, "") } : null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export {
|
|
154
|
+
normalizeAmountPhrases,
|
|
155
|
+
resolveAmountText,
|
|
156
|
+
diceRollOf,
|
|
157
|
+
diceRollPrefix
|
|
158
|
+
};
|