@archivist-gg/dnd5e 0.3.17 → 0.3.19
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-7QN7XSAK.js → chunk-3SFGWFVQ.js} +1 -1
- package/dist/{chunk-2UDSN6VW.js → chunk-3SIUAFDQ.js} +1 -1
- package/dist/chunk-4J6DS3EJ.js +30 -0
- package/dist/{chunk-RLGQ5PZZ.js → chunk-5JXFJ5AU.js} +11 -1
- package/dist/{chunk-TULQ4FFX.js → chunk-64VNLMSG.js} +31 -9
- package/dist/{chunk-JSM6JFZR.js → chunk-7XJHI5H5.js} +2 -2
- package/dist/{chunk-YD2VAHA6.js → chunk-B2QHP6UF.js} +2 -2
- package/dist/{chunk-AZRGFUSR.js → chunk-BJGOSM76.js} +1 -1
- package/dist/{chunk-JCMUVZIK.js → chunk-BJWSOQUC.js} +1 -1
- package/dist/{chunk-ONTGZR5T.js → chunk-EJD47JHL.js} +64 -32
- package/dist/{chunk-FANQVQ3D.js → chunk-FJYBLXV7.js} +2 -2
- package/dist/{chunk-PQZ4LM4Z.js → chunk-FMUD3LDV.js} +1 -1
- package/dist/{chunk-PKX6TGRE.js → chunk-FMYWORTP.js} +2 -2
- package/dist/{chunk-G6PBI2BU.js → chunk-FVXLP7P3.js} +1 -1
- package/dist/{chunk-MBX25B6D.js → chunk-GVWEFECG.js} +1 -1
- package/dist/{chunk-Y5VVP73C.js → chunk-HY2SRSVM.js} +1 -1
- package/dist/{chunk-2JSQE3DD.js → chunk-JXWNXIIZ.js} +13 -0
- package/dist/{chunk-VRV3NNTA.js → chunk-LICYHPI3.js} +81 -5
- package/dist/{chunk-LF5AGJA4.js → chunk-LNT64X7C.js} +1 -1
- package/dist/{chunk-6EI737IO.js → chunk-NKZMQV2C.js} +1 -1
- package/dist/{chunk-T6QIF5XR.js → chunk-NTU2DXNG.js} +9 -2
- package/dist/{chunk-3VZZDKRA.js → chunk-NXUY5XQN.js} +63 -15
- package/dist/{chunk-QZSWN2KT.js → chunk-NZO7M5GV.js} +1 -1
- package/dist/{chunk-5MXFW4O3.js → chunk-OOL4KMG2.js} +1 -1
- package/dist/{chunk-H5PTKYXL.js → chunk-QA3YCOML.js} +1 -1
- package/dist/{chunk-3MGQFFNE.js → chunk-QFWQKS3M.js} +1 -1
- package/dist/{chunk-HTYMW5CH.js → chunk-RD2MID3M.js} +67 -3
- package/dist/{chunk-PXVNAY7T.js → chunk-TRBGC4ZG.js} +29 -1
- package/dist/{chunk-UUBJCNQU.js → chunk-UJCK5IW4.js} +2 -2
- package/dist/{chunk-OFCSP6MT.js → chunk-UNYR5GLI.js} +1 -1
- package/dist/{chunk-DOXSFYLH.js → chunk-VN5DLURA.js} +2 -2
- package/dist/{chunk-7ATNGKBS.js → chunk-VP5TIXDK.js} +1 -1
- package/dist/{chunk-QH36K2PU.js → chunk-WOHX7YTH.js} +7 -0
- package/dist/{chunk-YKL6SHRJ.js → chunk-XTEFPUSN.js} +1 -1
- package/dist/{chunk-RYLXAYIQ.js → chunk-ZOWKWMD2.js} +1 -1
- package/dist/class/class.codec.js +6 -6
- package/dist/class/class.parser.js +5 -5
- package/dist/class/class.schema.js +4 -4
- package/dist/dnd/amount-text.d.ts +4 -0
- package/dist/dnd/amount-text.js +3 -1
- package/dist/entities/registry-revision.d.ts +25 -0
- package/dist/entities/registry-revision.js +10 -0
- package/dist/feat/feat.codec.js +5 -5
- package/dist/feat/feat.parser.js +4 -4
- package/dist/feat/feat.schema.d.ts +9 -0
- package/dist/feat/feat.schema.js +3 -3
- package/dist/index.js +3720 -338
- 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 -5
- package/dist/optional-feature/optional-feature.parser.js +4 -4
- package/dist/optional-feature/optional-feature.schema.d.ts +9 -0
- package/dist/optional-feature/optional-feature.schema.js +3 -3
- package/dist/pc/pc.additional-spells.d.ts +16 -2
- package/dist/pc/pc.additional-spells.js +4 -1
- package/dist/pc/pc.amount-bindings.d.ts +11 -2
- package/dist/pc/pc.amount-bindings.js +6 -1
- package/dist/pc/pc.decision-engine.d.ts +8 -0
- package/dist/pc/pc.decision-engine.js +13 -10
- package/dist/pc/pc.entry-overrides.js +3 -2
- package/dist/pc/pc.equipment.js +5 -4
- package/dist/pc/pc.feature-effects.d.ts +9 -2
- package/dist/pc/pc.feature-effects.js +15 -2
- package/dist/pc/pc.infusions.js +3 -2
- package/dist/pc/pc.member-choices.d.ts +33 -1
- package/dist/pc/pc.member-choices.js +12 -5
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.js +3 -2
- package/dist/pc/pc.proficiencies.d.ts +14 -0
- package/dist/pc/pc.proficiencies.js +68 -19
- package/dist/pc/pc.proficiency-normalize.d.ts +14 -0
- package/dist/pc/pc.proficiency-normalize.js +9 -3
- package/dist/pc/pc.proficiency-query.js +1 -1
- package/dist/pc/pc.recalc.js +151 -55
- package/dist/pc/pc.resolver.d.ts +4 -1
- package/dist/pc/pc.resolver.js +10 -9
- package/dist/pc/pc.rest.js +3 -2
- package/dist/pc/pc.schema.d.ts +19 -0
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.spell-scope.d.ts +22 -0
- package/dist/pc/pc.tool-picks.js +2 -2
- package/dist/pc/pc.types.d.ts +65 -4
- 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 +9 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.js +3 -3
- 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 +2 -2
- package/dist/types/feature-effect.d.ts +18 -0
- package/dist/types/optional-feature.types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
backgroundCodec
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-3SIUAFDQ.js";
|
|
4
|
+
import "../chunk-NKZMQV2C.js";
|
|
5
|
+
import "../chunk-QFWQKS3M.js";
|
|
6
6
|
import "../chunk-IN4M4X7P.js";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-OOL4KMG2.js";
|
|
8
|
+
import "../chunk-JXWNXIIZ.js";
|
|
9
9
|
import "../chunk-UA5KS2PL.js";
|
|
10
10
|
export {
|
|
11
11
|
backgroundCodec
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseBackground
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-NKZMQV2C.js";
|
|
4
|
+
import "../chunk-QFWQKS3M.js";
|
|
5
5
|
import "../chunk-IN4M4X7P.js";
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-OOL4KMG2.js";
|
|
7
|
+
import "../chunk-JXWNXIIZ.js";
|
|
8
8
|
import "../chunk-UA5KS2PL.js";
|
|
9
9
|
export {
|
|
10
10
|
parseBackground
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
backgroundEntitySchema,
|
|
3
3
|
langProfSchema
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-QFWQKS3M.js";
|
|
5
5
|
import "../chunk-IN4M4X7P.js";
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-OOL4KMG2.js";
|
|
7
|
+
import "../chunk-JXWNXIIZ.js";
|
|
8
8
|
import "../chunk-UA5KS2PL.js";
|
|
9
9
|
export {
|
|
10
10
|
backgroundEntitySchema,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/entities/registry-revision.ts
|
|
2
|
+
function registryRevision(registry) {
|
|
3
|
+
const r = registry == null ? void 0 : registry.revision;
|
|
4
|
+
return typeof r === "number" ? r : void 0;
|
|
5
|
+
}
|
|
6
|
+
function memoByRevision(cache, registry, compute) {
|
|
7
|
+
const revision = registryRevision(registry);
|
|
8
|
+
if (revision === void 0) return compute();
|
|
9
|
+
const hit = cache.get(registry);
|
|
10
|
+
if (hit && hit.revision === revision) return hit.value;
|
|
11
|
+
const value = compute();
|
|
12
|
+
cache.set(registry, { revision, value });
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
var BUCKETS = /* @__PURE__ */ new WeakMap();
|
|
16
|
+
function bucketOf(registry, type) {
|
|
17
|
+
const byType = memoByRevision(BUCKETS, registry, () => /* @__PURE__ */ new Map());
|
|
18
|
+
let bucket = byType.get(type);
|
|
19
|
+
if (!bucket) {
|
|
20
|
+
bucket = registry.search("", type, Number.POSITIVE_INFINITY);
|
|
21
|
+
byType.set(type, bucket);
|
|
22
|
+
}
|
|
23
|
+
return bucket;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
registryRevision,
|
|
28
|
+
memoByRevision,
|
|
29
|
+
bucketOf
|
|
30
|
+
};
|
|
@@ -7,10 +7,20 @@ var proficiencyLabel = (raw) => {
|
|
|
7
7
|
if (!/\s/.test(text) || text === text.toLowerCase()) return humanizeProficiency(toProfSlug(raw));
|
|
8
8
|
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
9
9
|
};
|
|
10
|
+
var weaponProfKey = (raw) => {
|
|
11
|
+
const key = normKey(raw);
|
|
12
|
+
const bare = key.split(" ").filter((w) => w !== "weapon").join(" ");
|
|
13
|
+
return bare === "simple" || bare === "martial" ? bare : key;
|
|
14
|
+
};
|
|
15
|
+
var armorProfKey = (raw) => normKey(raw).split(" ").filter((w) => w !== "armor").join(" ");
|
|
16
|
+
var proficiencyKey = (kind, raw) => kind === "weapons" ? weaponProfKey(raw) : kind === "armor" ? armorProfKey(raw) : toProfSlug(raw);
|
|
10
17
|
|
|
11
18
|
export {
|
|
12
19
|
normKey,
|
|
13
20
|
toProfSlug,
|
|
14
21
|
humanizeProficiency,
|
|
15
|
-
proficiencyLabel
|
|
22
|
+
proficiencyLabel,
|
|
23
|
+
weaponProfKey,
|
|
24
|
+
armorProfKey,
|
|
25
|
+
proficiencyKey
|
|
16
26
|
};
|
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-TOM66P2P.js";
|
|
4
4
|
import {
|
|
5
5
|
toProfSlug
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5JXFJ5AU.js";
|
|
7
|
+
import {
|
|
8
|
+
memberSpellTargets
|
|
9
|
+
} from "./chunk-RD2MID3M.js";
|
|
7
10
|
import {
|
|
8
11
|
warnOnce
|
|
9
12
|
} from "./chunk-LVQLWRCU.js";
|
|
@@ -42,7 +45,8 @@ function emptyFeatureEffectTotals() {
|
|
|
42
45
|
critRange: 20,
|
|
43
46
|
extraAttack: 0,
|
|
44
47
|
attackNotes: [],
|
|
45
|
-
damageBonuses: []
|
|
48
|
+
damageBonuses: [],
|
|
49
|
+
spellDamageBonuses: []
|
|
46
50
|
};
|
|
47
51
|
}
|
|
48
52
|
function pushUnique(list, value) {
|
|
@@ -87,14 +91,20 @@ function assembleEffectFeatures(resolved) {
|
|
|
87
91
|
for (const a of aliases) activeBuffs.add(a);
|
|
88
92
|
const buffFeatures = [];
|
|
89
93
|
const pushBoon = (item, pool) => {
|
|
90
|
-
var _a2, _b2, _c2, _d2, _e2, _f2, _g2;
|
|
94
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k;
|
|
91
95
|
const e = item.entity;
|
|
92
96
|
if (!e || item.itemBound === true || ((_b2 = (_a2 = e.effects) == null ? void 0 : _a2.length) != null ? _b2 : 0) === 0) return;
|
|
97
|
+
const block = (_f2 = (_e2 = (_d2 = (_c2 = resolved.classes) == null ? void 0 : _c2[pool.classIndex]) == null ? void 0 : _d2.choices) == null ? void 0 : _e2[pool.anchorLevel]) != null ? _f2 : {};
|
|
98
|
+
const spellTargets = memberSpellTargets(e, (id) => {
|
|
99
|
+
var _a3;
|
|
100
|
+
return block[`${pool.id}:${(_a3 = item.key) != null ? _a3 : item.slug}:${id}`];
|
|
101
|
+
});
|
|
93
102
|
buffFeatures.push({
|
|
94
|
-
feature: { id: item.slug, name: e.name, activatable: (
|
|
103
|
+
feature: { id: item.slug, name: e.name, activatable: (_g2 = e.activatable) != null ? _g2 : false, effects: e.effects },
|
|
95
104
|
// source is inert for the fold; attribute to the pool's owning class
|
|
96
105
|
// (never a hardcoded class) so the generic engine carries no homebrew name.
|
|
97
|
-
source: { kind: "class", slug: (
|
|
106
|
+
source: { kind: "class", slug: (_k = (_j2 = (_i2 = (_h2 = resolved.classes) == null ? void 0 : _h2[pool.classIndex]) == null ? void 0 : _i2.entity) == null ? void 0 : _j2.slug) != null ? _k : pool.id, level: pool.anchorLevel },
|
|
107
|
+
...spellTargets ? { spellTargets } : {}
|
|
98
108
|
});
|
|
99
109
|
};
|
|
100
110
|
for (const pool of (_g = resolved.pools) != null ? _g : []) {
|
|
@@ -119,7 +129,7 @@ function computeFeatureEffects(features, opts) {
|
|
|
119
129
|
if (!foldsNow(rf, (_a = opts == null ? void 0 : opts.activeBuffs) != null ? _a : /* @__PURE__ */ new Set())) continue;
|
|
120
130
|
const level = (_b = opts == null ? void 0 : opts.levelFor) == null ? void 0 : _b.call(opts, rf.source);
|
|
121
131
|
for (const eff of selfEffectsOf(rf.feature)) {
|
|
122
|
-
applyEffect(out, columnScaledRider(eff, rf, level, opts == null ? void 0 : opts.tableDiceFor), (_c = rf.feature.name) != null ? _c : "Feature", level, rf.source);
|
|
132
|
+
applyEffect(out, columnScaledRider(eff, rf, level, opts == null ? void 0 : opts.tableDiceFor), (_c = rf.feature.name) != null ? _c : "Feature", level, rf.source, rf.spellTargets);
|
|
123
133
|
}
|
|
124
134
|
}
|
|
125
135
|
return out;
|
|
@@ -198,8 +208,8 @@ function riderScope(appliesTo) {
|
|
|
198
208
|
const words = Array.isArray(appliesTo) ? appliesTo : [appliesTo];
|
|
199
209
|
return words.includes("weapon") ? void 0 : [...words];
|
|
200
210
|
}
|
|
201
|
-
function applyEffect(out, eff, label, level, owner) {
|
|
202
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
211
|
+
function applyEffect(out, eff, label, level, owner, targets) {
|
|
212
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
203
213
|
switch (eff.kind) {
|
|
204
214
|
case "initiative-bonus":
|
|
205
215
|
out.initiative_bonus += eff.value;
|
|
@@ -331,10 +341,22 @@ function applyEffect(out, eff, label, level, owner) {
|
|
|
331
341
|
...owner ? { owner } : {}
|
|
332
342
|
});
|
|
333
343
|
}
|
|
344
|
+
if (eff.applies_to === "spell" || eff.applies_to === "all") {
|
|
345
|
+
const spellScope = (_j = eff.spell_scope) != null ? _j : eff.applies_to === "all" ? {} : void 0;
|
|
346
|
+
out.spellDamageBonuses.push({
|
|
347
|
+
amount: eff.amount,
|
|
348
|
+
damage_type: eff.damage_type,
|
|
349
|
+
source: label,
|
|
350
|
+
...eff.condition ? { condition: eff.condition } : {},
|
|
351
|
+
...owner ? { owner } : {},
|
|
352
|
+
...targets ? { targets } : {},
|
|
353
|
+
...spellScope ? { scope: spellScope } : {}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
334
356
|
break;
|
|
335
357
|
case "ability-score-increase":
|
|
336
358
|
if (eff.abilities === "chosen") break;
|
|
337
|
-
for (const ab of eff.abilities) out.ability_bonus[ab] = ((
|
|
359
|
+
for (const ab of eff.abilities) out.ability_bonus[ab] = ((_k = out.ability_bonus[ab]) != null ? _k : 0) + eff.amount;
|
|
338
360
|
break;
|
|
339
361
|
default:
|
|
340
362
|
break;
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
} from "./chunk-EJP263OP.js";
|
|
10
10
|
import {
|
|
11
11
|
normKey
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5JXFJ5AU.js";
|
|
13
13
|
import {
|
|
14
14
|
WEAPON_DEFAULT_ACTION_COST,
|
|
15
15
|
resolveEntryEntity
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-NXUY5XQN.js";
|
|
17
17
|
import {
|
|
18
18
|
readNumericBonus
|
|
19
19
|
} from "./chunk-HHBD4SQ6.js";
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
} from "./chunk-ZJXSXVFP.js";
|
|
9
9
|
import {
|
|
10
10
|
choiceSchema
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-OOL4KMG2.js";
|
|
12
12
|
import {
|
|
13
13
|
featureEffectSchema
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JXWNXIIZ.js";
|
|
15
15
|
|
|
16
16
|
// src/schemas/feature-schema.ts
|
|
17
17
|
import { z as z2 } from "zod";
|
|
@@ -9,24 +9,33 @@ import {
|
|
|
9
9
|
classToolPicks,
|
|
10
10
|
expandToolPool,
|
|
11
11
|
toolCategoriesOf
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QA3YCOML.js";
|
|
13
13
|
import {
|
|
14
14
|
assembleEffectFeatures,
|
|
15
15
|
collectProficiencyEffectGrants
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-64VNLMSG.js";
|
|
17
17
|
import {
|
|
18
18
|
ALL_LANGUAGES,
|
|
19
19
|
ALL_SKILL_SLUGS,
|
|
20
20
|
ALL_TOOLS
|
|
21
21
|
} from "./chunk-KU3YLF6D.js";
|
|
22
|
+
import {
|
|
23
|
+
humanizeProficiency,
|
|
24
|
+
proficiencyLabel,
|
|
25
|
+
toProfSlug
|
|
26
|
+
} from "./chunk-5JXFJ5AU.js";
|
|
22
27
|
import {
|
|
23
28
|
featOfSite,
|
|
24
29
|
featPickSites,
|
|
25
30
|
isTargetChoice,
|
|
26
31
|
memberChoices,
|
|
27
32
|
poolMemberSites,
|
|
28
|
-
poolMemberSitesOf
|
|
29
|
-
|
|
33
|
+
poolMemberSitesOf,
|
|
34
|
+
raceFeatSites
|
|
35
|
+
} from "./chunk-RD2MID3M.js";
|
|
36
|
+
import {
|
|
37
|
+
collectAdditionalSpells
|
|
38
|
+
} from "./chunk-LICYHPI3.js";
|
|
30
39
|
import {
|
|
31
40
|
resolveFeatureResources,
|
|
32
41
|
resolveResourceIndex
|
|
@@ -42,18 +51,13 @@ import {
|
|
|
42
51
|
flattenAsiOrFeat,
|
|
43
52
|
resolveLegacyAsiFeat
|
|
44
53
|
} from "./chunk-LBEXLN6I.js";
|
|
45
|
-
import {
|
|
46
|
-
humanizeProficiency,
|
|
47
|
-
proficiencyLabel,
|
|
48
|
-
toProfSlug
|
|
49
|
-
} from "./chunk-RLGQ5PZZ.js";
|
|
50
54
|
import {
|
|
51
55
|
bindFeatureConsumers,
|
|
52
56
|
buildInfusionContext,
|
|
53
57
|
resolveAllPools,
|
|
54
58
|
resolveOptionRows,
|
|
55
59
|
strandedPicks
|
|
56
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-NXUY5XQN.js";
|
|
57
61
|
import {
|
|
58
62
|
countColumnsFor,
|
|
59
63
|
readTableColumn
|
|
@@ -61,9 +65,6 @@ import {
|
|
|
61
65
|
import {
|
|
62
66
|
recognizeDecision
|
|
63
67
|
} from "./chunk-YHYTW5QA.js";
|
|
64
|
-
import {
|
|
65
|
-
collectAdditionalSpells
|
|
66
|
-
} from "./chunk-VRV3NNTA.js";
|
|
67
68
|
import {
|
|
68
69
|
isItemEntity,
|
|
69
70
|
resolveEntityForEntry
|
|
@@ -75,6 +76,9 @@ import {
|
|
|
75
76
|
import {
|
|
76
77
|
warnOnce
|
|
77
78
|
} from "./chunk-LVQLWRCU.js";
|
|
79
|
+
import {
|
|
80
|
+
bucketOf
|
|
81
|
+
} from "./chunk-4J6DS3EJ.js";
|
|
78
82
|
import {
|
|
79
83
|
isValidMaxFormula
|
|
80
84
|
} from "./chunk-EVMUJYUD.js";
|
|
@@ -522,7 +526,7 @@ function buildSubclassItem(choice, source, level, featureName, c, ctx, ownerBare
|
|
|
522
526
|
};
|
|
523
527
|
}
|
|
524
528
|
function visitProficiencyChoices(resolved, visit) {
|
|
525
|
-
var _a, _b, _c;
|
|
529
|
+
var _a, _b, _c, _d, _e;
|
|
526
530
|
const walk = (choices, read) => {
|
|
527
531
|
for (const ch of choices != null ? choices : []) {
|
|
528
532
|
visit(ch, read(ch.id));
|
|
@@ -539,11 +543,11 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
539
543
|
const featBySlug = new Map(((_b = resolved.feats) != null ? _b : []).map((f) => [f.slug, f]));
|
|
540
544
|
const memberSites = poolMemberSitesOf(resolved);
|
|
541
545
|
const featSites = featPickSites(resolved.classes, memberSites, (ci) => {
|
|
542
|
-
var _a2, _b2, _c2,
|
|
543
|
-
return (
|
|
546
|
+
var _a2, _b2, _c2, _d2;
|
|
547
|
+
return (_d2 = (_c2 = (_b2 = (_a2 = resolved.classes) == null ? void 0 : _a2[ci]) == null ? void 0 : _b2.entity) == null ? void 0 : _c2.slug) != null ? _d2 : null;
|
|
544
548
|
});
|
|
545
549
|
resolved.classes.forEach((c, i) => {
|
|
546
|
-
var _a2, _b2, _c2,
|
|
550
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
547
551
|
if (!c.entity) return;
|
|
548
552
|
const entity = c.entity;
|
|
549
553
|
const readAt = (lvl) => (id) => {
|
|
@@ -570,7 +574,7 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
570
574
|
}
|
|
571
575
|
for (const site of featSites) {
|
|
572
576
|
if (site.classIndex !== i) continue;
|
|
573
|
-
const feat = (
|
|
577
|
+
const feat = (_e2 = featBySlug.get(stripRef(site.slug))) != null ? _e2 : featOfSite(site, (_d2 = resolved.feats) != null ? _d2 : []);
|
|
574
578
|
if (!feat) continue;
|
|
575
579
|
walk(feat.choices, site.read);
|
|
576
580
|
}
|
|
@@ -592,6 +596,10 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
592
596
|
const of = featBySlug.get(resolved.originFeatSlug);
|
|
593
597
|
if (of) walk(of.choices, (id) => oc[`background:feat:${id}`]);
|
|
594
598
|
}
|
|
599
|
+
for (const site of raceFeatSites(resolved.race, oc)) {
|
|
600
|
+
const rf = (_e = featBySlug.get(stripRef(site.slug))) != null ? _e : ((_d = resolved.feats) != null ? _d : []).find((f) => bareEntitySlug(f.slug) === bareEntitySlug(site.slug));
|
|
601
|
+
if (rf) walk(rf.choices, site.read);
|
|
602
|
+
}
|
|
595
603
|
}
|
|
596
604
|
var filterToPool = (vals, pool) => pool ? vals.map((v) => matchPool(v, pool)).filter((v) => !!v) : vals;
|
|
597
605
|
function collectChosenProficiencies(resolved) {
|
|
@@ -628,6 +636,14 @@ function proficiencyEntryFor(raw, vocab, origin, sources, expertise) {
|
|
|
628
636
|
return { value, label, sources, origin, ...expertise ? { expertise: true } : {} };
|
|
629
637
|
}
|
|
630
638
|
function computeEffectiveProficiencies(resolved) {
|
|
639
|
+
const c = composeLanguageToolProficiencies(resolved);
|
|
640
|
+
return { languages: c.languages.kept, tools: c.tools.kept };
|
|
641
|
+
}
|
|
642
|
+
function computeSuppressedProficiencies(resolved) {
|
|
643
|
+
const c = composeLanguageToolProficiencies(resolved);
|
|
644
|
+
return { languages: c.languages.suppressed, tools: c.tools.suppressed };
|
|
645
|
+
}
|
|
646
|
+
function composeLanguageToolProficiencies(resolved) {
|
|
631
647
|
const grants = collectProficiencyGrants(resolved);
|
|
632
648
|
const chosen = collectChosenProficiencies(resolved);
|
|
633
649
|
const build = (domain) => {
|
|
@@ -673,7 +689,9 @@ function computeEffectiveProficiencies(resolved) {
|
|
|
673
689
|
}
|
|
674
690
|
}
|
|
675
691
|
const suppressed = /* @__PURE__ */ new Set([...removes.map((r) => toProfSlug(r)), ...triSuppressed]);
|
|
676
|
-
|
|
692
|
+
const byLabel = (a, b) => a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
|
|
693
|
+
const kept = [...byValue.values()].filter((e) => !suppressed.has(toProfSlug(e.value))).sort(byLabel);
|
|
694
|
+
return { kept, suppressed: [...byValue.values()].filter((e) => suppressed.has(toProfSlug(e.value))).sort(byLabel) };
|
|
677
695
|
};
|
|
678
696
|
return { languages: build("languages"), tools: build("tools") };
|
|
679
697
|
}
|
|
@@ -1160,7 +1178,7 @@ function resolveOriginFeat(entities, originFeatRef, ownerSlug) {
|
|
|
1160
1178
|
const baseSlug = base && base !== rawTail ? wikilinkTailSlug(`[[${base}]]`) : null;
|
|
1161
1179
|
const baseInner = baseSlug ? inner.slice(0, inner.length - rawTail.length) + base : null;
|
|
1162
1180
|
const prefix = (ownerSlug == null ? void 0 : ownerSlug.includes("_")) ? ownerSlug.slice(0, ownerSlug.indexOf("_")) : null;
|
|
1163
|
-
const feats = entities
|
|
1181
|
+
const feats = bucketOf(entities, "feat");
|
|
1164
1182
|
const byPath = (p) => feats.find((f) => f.filePath === `${p}.md` || f.filePath.endsWith(`/${p}.md`));
|
|
1165
1183
|
const sameCompendiumTail = (s) => prefix ? feats.find((f) => f.slug.startsWith(`${prefix}_feat_`) && f.slug.endsWith(`_${s}`)) : void 0;
|
|
1166
1184
|
const anyTail = (s) => feats.find((f) => f.slug.endsWith(`_${s}`));
|
|
@@ -1247,6 +1265,14 @@ var PCResolver = class {
|
|
|
1247
1265
|
if (originFeat && background && !featVia.has(originFeat.feat.slug)) {
|
|
1248
1266
|
featVia.set(originFeat.feat.slug, { kind: "background", slug: background.slug });
|
|
1249
1267
|
}
|
|
1268
|
+
const raceFeats = [];
|
|
1269
|
+
for (const site of raceFeatSites(race, character.origin_choices)) {
|
|
1270
|
+
const f = lookup(`[[${site.slug}]]`, "feat");
|
|
1271
|
+
if (!f) continue;
|
|
1272
|
+
raceFeats.push({ feat: f, read: site.read });
|
|
1273
|
+
if (!feats.some((x) => x.slug === f.slug)) feats.push(f);
|
|
1274
|
+
if (!featVia.has(f.slug)) featVia.set(f.slug, site.via);
|
|
1275
|
+
}
|
|
1250
1276
|
const totalLevel = classes.reduce((sum, c) => sum + c.level, 0);
|
|
1251
1277
|
const features = collectResolvedFeatures(race, classes, background, feats, featVia);
|
|
1252
1278
|
const extraFeatures = collectChosenGrantedFeatures(character, classes, this.entities, race, background, memberSites);
|
|
@@ -1277,6 +1303,7 @@ var PCResolver = class {
|
|
|
1277
1303
|
const read = (childId) => oc[`background:feat:${childId}`];
|
|
1278
1304
|
spells.push(...collectFeatGrantedSpells(originFeat.feat, read, this.entities, warnings));
|
|
1279
1305
|
}
|
|
1306
|
+
for (const rf of raceFeats) spells.push(...collectFeatGrantedSpells(rf.feat, rf.read, this.entities, warnings));
|
|
1280
1307
|
for (const site of featSites) {
|
|
1281
1308
|
const reg = this.entities.getByTypeAndSlug("feat", site.slug);
|
|
1282
1309
|
if (!reg) continue;
|
|
@@ -1307,16 +1334,6 @@ var PCResolver = class {
|
|
|
1307
1334
|
return p ? effectiveSpellcastingAbility(c.entity.slug, p.ability, character.overrides) : null;
|
|
1308
1335
|
}).find((a) => a != null)) != null ? _h : null;
|
|
1309
1336
|
spells.push(...collectItemGrantedSpells(character, ownSpellcastingAbility, this.entities, warnings));
|
|
1310
|
-
spells.push(...collectAdditionalSpells({
|
|
1311
|
-
race,
|
|
1312
|
-
feats,
|
|
1313
|
-
classes,
|
|
1314
|
-
totalLevel,
|
|
1315
|
-
ownAbility: ownSpellcastingAbility,
|
|
1316
|
-
alreadyCollected: spells,
|
|
1317
|
-
entities: this.entities,
|
|
1318
|
-
warnings
|
|
1319
|
-
}));
|
|
1320
1337
|
const chosenMasteries = collectChosenWeaponMasteries(character);
|
|
1321
1338
|
if (chosenMasteries.full.length > 0) {
|
|
1322
1339
|
const target = features.find(
|
|
@@ -1348,13 +1365,27 @@ var PCResolver = class {
|
|
|
1348
1365
|
...originFeatSlug ? { originFeatSlug } : {},
|
|
1349
1366
|
totalLevel,
|
|
1350
1367
|
features,
|
|
1351
|
-
spells:
|
|
1368
|
+
spells: [],
|
|
1352
1369
|
pools: [],
|
|
1353
1370
|
resources: featureResources,
|
|
1354
1371
|
weaponMasteries: chosenMasteries.bare,
|
|
1355
1372
|
state: character.state
|
|
1356
1373
|
};
|
|
1357
1374
|
resolvedCharacter.pools = resolveAllPools(resolvedCharacter, this.entities, featureResources);
|
|
1375
|
+
spells.push(...collectAdditionalSpells({
|
|
1376
|
+
race,
|
|
1377
|
+
feats,
|
|
1378
|
+
classes,
|
|
1379
|
+
totalLevel,
|
|
1380
|
+
ownAbility: ownSpellcastingAbility,
|
|
1381
|
+
alreadyCollected: spells,
|
|
1382
|
+
entities: this.entities,
|
|
1383
|
+
warnings,
|
|
1384
|
+
// SRD-G T4: the race's lineage and spellcasting-ability picks select and qualify its spell blocks.
|
|
1385
|
+
raceChoice: (id) => oc[`race:${id}`],
|
|
1386
|
+
pools: resolvedCharacter.pools
|
|
1387
|
+
}));
|
|
1388
|
+
resolvedCharacter.spells = dedupeResolvedSpells(spells);
|
|
1358
1389
|
resolvedCharacter.resources = resolveResourceIndex(resolvedCharacter);
|
|
1359
1390
|
resolvedCharacter.features = bindFeatureConsumers(resolvedCharacter.features, resolvedCharacter.resources, classes);
|
|
1360
1391
|
const infusions = buildInfusionContext(character, resolvedCharacter, this.entities);
|
|
@@ -1425,7 +1456,7 @@ function collectItemGrantedSpells(character, ownAbility, entities, warnings) {
|
|
|
1425
1456
|
function dedupeResolvedSpells(spells) {
|
|
1426
1457
|
const byKey = /* @__PURE__ */ new Map();
|
|
1427
1458
|
for (const s of spells) {
|
|
1428
|
-
const key = s.source === "item" ? `${s.slug}#${s.entryIndex}` : s.slug;
|
|
1459
|
+
const key = s.source === "item" ? `${s.slug}#${s.entryIndex}` : s.atWill ? `${s.slug}#atwill` : s.slug;
|
|
1429
1460
|
const existing = byKey.get(key);
|
|
1430
1461
|
if (!existing) {
|
|
1431
1462
|
byKey.set(key, s);
|
|
@@ -1801,6 +1832,7 @@ export {
|
|
|
1801
1832
|
__categoryToEntitySelectForTest,
|
|
1802
1833
|
collectChosenProficiencies,
|
|
1803
1834
|
computeEffectiveProficiencies,
|
|
1835
|
+
computeSuppressedProficiencies,
|
|
1804
1836
|
collectChosenAbilityPoints,
|
|
1805
1837
|
buildDecisionLedger
|
|
1806
1838
|
};
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-ZJXSXVFP.js";
|
|
5
5
|
import {
|
|
6
6
|
choiceSchema
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OOL4KMG2.js";
|
|
8
8
|
import {
|
|
9
9
|
featureEffectSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JXWNXIIZ.js";
|
|
11
11
|
import {
|
|
12
12
|
additionalSpellsEntrySchema,
|
|
13
13
|
imageField,
|
|
@@ -4,6 +4,15 @@ var abilityEnum = z.enum(["str", "dex", "con", "int", "wis", "cha"]);
|
|
|
4
4
|
var subjectField = z.string().min(1).optional();
|
|
5
5
|
var conditionField = z.string().optional();
|
|
6
6
|
var weaponScopeEnum = z.enum(["weapon", "melee", "ranged", "unarmed", "finesse", "thrown"]);
|
|
7
|
+
var spellScopeSchema = z.object({
|
|
8
|
+
list: z.string().min(1).optional(),
|
|
9
|
+
level: z.number().int().min(0).max(9).optional(),
|
|
10
|
+
school: z.string().min(1).optional(),
|
|
11
|
+
damage_types: z.array(z.string().min(1)).min(1).optional(),
|
|
12
|
+
damage_type_pick: z.string().min(1).optional(),
|
|
13
|
+
spells: z.array(z.string().min(1)).min(1).optional(),
|
|
14
|
+
once: z.boolean().optional()
|
|
15
|
+
}).strict();
|
|
7
16
|
var featureEffectSchema = z.discriminatedUnion("kind", [
|
|
8
17
|
z.object({ kind: z.literal("initiative-bonus"), value: z.number().int(), condition: conditionField, subject: subjectField }),
|
|
9
18
|
z.object({ kind: z.literal("skill-bonus"), skills: z.array(z.string().min(1)).nonempty(), ability: abilityEnum, minimum: z.number().int().optional(), condition: conditionField, subject: subjectField }),
|
|
@@ -83,6 +92,10 @@ var featureEffectSchema = z.discriminatedUnion("kind", [
|
|
|
83
92
|
// ART-c1 Task 9b: `spell` and `all` as before, or a weapon scope, one word or an any-of list, which the engine
|
|
84
93
|
// evaluates per attack row (pc.recalc.ts `riderReachesRow`). `weapon`, like an absent value, reaches every row.
|
|
85
94
|
applies_to: z.union([z.enum(["spell", "all"]), weaponScopeEnum, z.array(weaponScopeEnum).min(1)]).optional(),
|
|
95
|
+
// The spells a `spell` or `all` rider reaches (Potent Spellcasting's Cleric cantrips, Empowered Evocation's Wizard
|
|
96
|
+
// evocation spells); pc.recalc.ts `spellsInScope` reads it. A `spell` rider without one reaches only the spells its
|
|
97
|
+
// pool member's data names (Agonizing Blast's target pick); an `all` rider without one reaches every damaging spell.
|
|
98
|
+
spell_scope: spellScopeSchema.optional(),
|
|
86
99
|
condition: conditionField,
|
|
87
100
|
subject: subjectField
|
|
88
101
|
}),
|