@archivist-gg/dnd5e 0.3.13 → 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-3LWMFYKS.js +57 -0
- package/dist/{chunk-4SLOJXJ4.js → chunk-3SFGWFVQ.js} +1 -1
- package/dist/{chunk-Q6UOHCCT.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-4BZ47YJ4.js → chunk-64VNLMSG.js} +59 -16
- package/dist/{chunk-XY6X2APM.js → chunk-7Q2VPKCD.js} +17 -0
- package/dist/{chunk-Q5XTEYHD.js → chunk-7XJHI5H5.js} +16 -9
- package/dist/{chunk-FPGXFD2M.js → chunk-B2QHP6UF.js} +2 -2
- package/dist/{chunk-HJQNK3J5.js → chunk-B3DP42OM.js} +1 -4
- package/dist/{chunk-MC5YJ4PB.js → chunk-BJGOSM76.js} +1 -1
- package/dist/{chunk-VDPRBUU5.js → chunk-BJWSOQUC.js} +1 -1
- package/dist/{chunk-QEO7LYTG.js → chunk-EJD47JHL.js} +181 -93
- package/dist/{chunk-X7VZY4ON.js → chunk-FJYBLXV7.js} +2 -2
- package/dist/{chunk-QSBJ6NEM.js → chunk-FMUD3LDV.js} +1 -1
- package/dist/{chunk-LVX6TQ3R.js → chunk-FMYWORTP.js} +2 -2
- package/dist/{chunk-PX25R3DK.js → chunk-FVXLP7P3.js} +1 -1
- package/dist/{chunk-XJRNEQPD.js → chunk-GVWEFECG.js} +1 -1
- package/dist/{chunk-R2V5LN3I.js → chunk-HY2SRSVM.js} +1 -1
- package/dist/{chunk-ZMJQUZQH.js → chunk-JXWNXIIZ.js} +24 -0
- package/dist/chunk-KR6JF3BF.js +14 -0
- package/dist/{chunk-DPM6V7YX.js → chunk-LICYHPI3.js} +82 -6
- package/dist/{chunk-J53ERF6K.js → chunk-LNT64X7C.js} +1 -1
- package/dist/{chunk-RQNJXADQ.js → chunk-NKZMQV2C.js} +1 -1
- package/dist/{chunk-UE6LKRXQ.js → chunk-NTU2DXNG.js} +24 -1
- package/dist/{chunk-T5GZBKIQ.js → chunk-NXUY5XQN.js} +168 -33
- package/dist/{chunk-M2OWVAZG.js → chunk-NZO7M5GV.js} +1 -1
- package/dist/{chunk-BRGLDWUP.js → chunk-OOL4KMG2.js} +7 -3
- package/dist/{chunk-MWCCGPG3.js → chunk-OOSRUJBI.js} +3 -2
- package/dist/{chunk-H5PTKYXL.js → chunk-QA3YCOML.js} +1 -1
- package/dist/{chunk-MUIU7RZ3.js → chunk-QFWQKS3M.js} +1 -1
- package/dist/chunk-RD2MID3M.js +292 -0
- package/dist/chunk-TRBGC4ZG.js +112 -0
- package/dist/{chunk-PLOSP4XQ.js → chunk-UJCK5IW4.js} +11 -2
- package/dist/{chunk-5KGV6TF7.js → chunk-UNYR5GLI.js} +1 -1
- package/dist/{chunk-JNNNBEUH.js → chunk-VN5DLURA.js} +7 -2
- package/dist/{chunk-EL6QPF6I.js → chunk-VP5TIXDK.js} +1 -1
- package/dist/chunk-WOHX7YTH.js +165 -0
- package/dist/{chunk-G7ED5H2G.js → chunk-XTEFPUSN.js} +1 -1
- package/dist/{chunk-6ZY3U6BQ.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.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 +42 -0
- package/dist/dnd/amount-text.js +15 -0
- package/dist/dnd/resource-words.d.ts +4 -0
- package/dist/dnd/resource-words.js +30 -0
- 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 +34 -0
- package/dist/feat/feat.schema.js +3 -3
- package/dist/index.js +4027 -383
- 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 +35 -0
- package/dist/optional-feature/optional-feature.schema.js +3 -2
- package/dist/pc/pc.additional-spells.d.ts +16 -2
- package/dist/pc/pc.additional-spells.js +5 -2
- package/dist/pc/pc.amount-bindings.d.ts +41 -0
- package/dist/pc/pc.amount-bindings.js +28 -0
- package/dist/pc/pc.decision-engine.d.ts +11 -0
- package/dist/pc/pc.decision-engine.js +20 -16
- package/dist/pc/pc.entry-overrides.js +3 -2
- package/dist/pc/pc.equipment.js +7 -5
- package/dist/pc/pc.feature-effects.d.ts +21 -2
- package/dist/pc/pc.feature-effects.js +15 -2
- package/dist/pc/pc.infusions.d.ts +9 -1
- package/dist/pc/pc.infusions.js +3 -2
- package/dist/pc/pc.member-choices.d.ts +122 -0
- package/dist/pc/pc.member-choices.js +39 -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 -2
- package/dist/pc/pc.proficiencies.d.ts +14 -0
- package/dist/pc/pc.proficiencies.js +72 -22
- 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 +7 -1
- package/dist/pc/pc.recalc.js +212 -99
- package/dist/pc/pc.resolver.d.ts +6 -2
- package/dist/pc/pc.resolver.js +16 -14
- package/dist/pc/pc.rest.js +4 -3
- package/dist/pc/pc.schema.d.ts +48 -2
- 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 +110 -6
- 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 +34 -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 +7 -2
- package/dist/types/feature-effect.d.ts +24 -0
- package/dist/types/optional-feature.types.d.ts +6 -1
- package/dist/types/selection-pool.d.ts +2 -2
- 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,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifyWeaponRange
|
|
3
|
+
} from "./chunk-YDGMBMYI.js";
|
|
4
|
+
|
|
5
|
+
// src/pc/pc.weapon-grant.ts
|
|
6
|
+
var PROPERTY_KEY = {
|
|
7
|
+
"2h": "two_handed",
|
|
8
|
+
"two-handed": "two_handed",
|
|
9
|
+
"two handed": "two_handed",
|
|
10
|
+
h: "heavy",
|
|
11
|
+
l: "light",
|
|
12
|
+
f: "finesse",
|
|
13
|
+
t: "thrown",
|
|
14
|
+
v: "versatile",
|
|
15
|
+
r: "reach",
|
|
16
|
+
a: "ammunition",
|
|
17
|
+
ld: "loading",
|
|
18
|
+
s: "special"
|
|
19
|
+
};
|
|
20
|
+
var propertyKey = (word) => {
|
|
21
|
+
var _a;
|
|
22
|
+
const w = word.trim().toLowerCase();
|
|
23
|
+
return (_a = PROPERTY_KEY[w]) != null ? _a : w.replace(/[\s-]+/g, "_");
|
|
24
|
+
};
|
|
25
|
+
var GRANT_RE = new RegExp(
|
|
26
|
+
"^(?:all\\s+)?(?:(melee|ranged)\\s+)?(simple|martial)(?:\\s+(melee|ranged))?\\s+weapons?\\s+(?:that|which)\\s+(have|has|don'?t\\s+have|do\\s+not\\s+have|doesn'?t\\s+have|does\\s+not\\s+have)\\s+the\\s+(.+?)\\s+propert(?:y|ies)\\.?$",
|
|
27
|
+
"i"
|
|
28
|
+
);
|
|
29
|
+
function parseQualifiedWeaponGrant(text) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const m = GRANT_RE.exec(text.replace(/’/g, "'").trim().replace(/\s+/g, " "));
|
|
32
|
+
if (!m) return null;
|
|
33
|
+
const range = (_b = (_a = m[1]) != null ? _a : m[3]) == null ? void 0 : _b.toLowerCase();
|
|
34
|
+
const properties = m[5].split(/\s*,\s*|\s+or\s+|\s+and\s+/i).map((w) => w.trim()).filter(Boolean).map(propertyKey);
|
|
35
|
+
if (properties.length === 0) return null;
|
|
36
|
+
return {
|
|
37
|
+
category: m[2].toLowerCase(),
|
|
38
|
+
...range ? { range } : {},
|
|
39
|
+
properties,
|
|
40
|
+
without: /n'?t|not/i.test(m[4])
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function qualifiedGrantCovers(text, weapon) {
|
|
44
|
+
const g = parseQualifiedWeaponGrant(text);
|
|
45
|
+
if (!g || typeof weapon.category !== "string") return false;
|
|
46
|
+
if (!new RegExp(`^${g.category}\\b`).test(weapon.category)) return false;
|
|
47
|
+
if (g.range) {
|
|
48
|
+
const melee = classifyWeaponRange(weapon).melee !== null;
|
|
49
|
+
if (g.range === "melee" !== melee) return false;
|
|
50
|
+
}
|
|
51
|
+
const has = g.properties.some((p) => weapon.properties.some((x) => x === p));
|
|
52
|
+
return g.without ? !has : has;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
qualifiedGrantCovers
|
|
57
|
+
};
|
|
@@ -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";
|
|
@@ -20,6 +23,7 @@ function emptyFeatureEffectTotals() {
|
|
|
20
23
|
initiative_bonus: 0,
|
|
21
24
|
initiative_terms: [],
|
|
22
25
|
skill_bonus_terms: [],
|
|
26
|
+
save_bonus_terms: [],
|
|
23
27
|
half_proficiency_terms: [],
|
|
24
28
|
hp_per_level_bonus: 0,
|
|
25
29
|
hp_per_level_terms: [],
|
|
@@ -41,7 +45,8 @@ function emptyFeatureEffectTotals() {
|
|
|
41
45
|
critRange: 20,
|
|
42
46
|
extraAttack: 0,
|
|
43
47
|
attackNotes: [],
|
|
44
|
-
damageBonuses: []
|
|
48
|
+
damageBonuses: [],
|
|
49
|
+
spellDamageBonuses: []
|
|
45
50
|
};
|
|
46
51
|
}
|
|
47
52
|
function pushUnique(list, value) {
|
|
@@ -86,14 +91,20 @@ function assembleEffectFeatures(resolved) {
|
|
|
86
91
|
for (const a of aliases) activeBuffs.add(a);
|
|
87
92
|
const buffFeatures = [];
|
|
88
93
|
const pushBoon = (item, pool) => {
|
|
89
|
-
var _a2, _b2, _c2, _d2, _e2, _f2, _g2;
|
|
94
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k;
|
|
90
95
|
const e = item.entity;
|
|
91
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
|
+
});
|
|
92
102
|
buffFeatures.push({
|
|
93
|
-
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 },
|
|
94
104
|
// source is inert for the fold; attribute to the pool's owning class
|
|
95
105
|
// (never a hardcoded class) so the generic engine carries no homebrew name.
|
|
96
|
-
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 } : {}
|
|
97
108
|
});
|
|
98
109
|
};
|
|
99
110
|
for (const pool of (_g = resolved.pools) != null ? _g : []) {
|
|
@@ -118,7 +129,7 @@ function computeFeatureEffects(features, opts) {
|
|
|
118
129
|
if (!foldsNow(rf, (_a = opts == null ? void 0 : opts.activeBuffs) != null ? _a : /* @__PURE__ */ new Set())) continue;
|
|
119
130
|
const level = (_b = opts == null ? void 0 : opts.levelFor) == null ? void 0 : _b.call(opts, rf.source);
|
|
120
131
|
for (const eff of selfEffectsOf(rf.feature)) {
|
|
121
|
-
applyEffect(out, eff, (_c = rf.feature.name) != null ? _c : "Feature", level);
|
|
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);
|
|
122
133
|
}
|
|
123
134
|
}
|
|
124
135
|
return out;
|
|
@@ -182,13 +193,23 @@ function scaled(base, key, scalesAt, level) {
|
|
|
182
193
|
}
|
|
183
194
|
return best;
|
|
184
195
|
}
|
|
196
|
+
function columnScaledRider(eff, rf, level, tableDiceFor) {
|
|
197
|
+
if (eff.kind !== "damage-bonus" || level === void 0 || !tableDiceFor) return eff;
|
|
198
|
+
const src = rf.source;
|
|
199
|
+
const column = rf.feature.name;
|
|
200
|
+
if (src.kind !== "class" && src.kind !== "subclass" || !column) return eff;
|
|
201
|
+
const atGain = tableDiceFor(src, column, src.level);
|
|
202
|
+
if (!atGain || atGain.toLowerCase() !== eff.amount.trim().toLowerCase()) return eff;
|
|
203
|
+
const now = tableDiceFor(src, column, level);
|
|
204
|
+
return now ? { ...eff, amount: now } : eff;
|
|
205
|
+
}
|
|
185
206
|
function riderScope(appliesTo) {
|
|
186
207
|
if (appliesTo === void 0 || appliesTo === "all" || appliesTo === "spell") return void 0;
|
|
187
208
|
const words = Array.isArray(appliesTo) ? appliesTo : [appliesTo];
|
|
188
209
|
return words.includes("weapon") ? void 0 : [...words];
|
|
189
210
|
}
|
|
190
|
-
function applyEffect(out, eff, label, level) {
|
|
191
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
211
|
+
function applyEffect(out, eff, label, level, owner, targets) {
|
|
212
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
192
213
|
switch (eff.kind) {
|
|
193
214
|
case "initiative-bonus":
|
|
194
215
|
out.initiative_bonus += eff.value;
|
|
@@ -202,10 +223,19 @@ function applyEffect(out, eff, label, level) {
|
|
|
202
223
|
label
|
|
203
224
|
});
|
|
204
225
|
break;
|
|
226
|
+
case "save-bonus":
|
|
227
|
+
out.save_bonus_terms.push({
|
|
228
|
+
saves: [...(_b = eff.saves) != null ? _b : []],
|
|
229
|
+
ability: eff.ability,
|
|
230
|
+
minimum: (_c = eff.minimum) != null ? _c : 0,
|
|
231
|
+
...eff.inactive_while ? { inactiveWhile: eff.inactive_while } : {},
|
|
232
|
+
label
|
|
233
|
+
});
|
|
234
|
+
break;
|
|
205
235
|
case "half-proficiency":
|
|
206
236
|
out.half_proficiency_terms.push({
|
|
207
|
-
skills: ((
|
|
208
|
-
round: (
|
|
237
|
+
skills: ((_d = eff.skills) != null ? _d : []).map(toProfSlug),
|
|
238
|
+
round: (_e = eff.round) != null ? _e : "down",
|
|
209
239
|
label
|
|
210
240
|
});
|
|
211
241
|
break;
|
|
@@ -272,7 +302,7 @@ function applyEffect(out, eff, label, level) {
|
|
|
272
302
|
}
|
|
273
303
|
case "roll-modifier": {
|
|
274
304
|
const rolls = eff.roll === "any" ? ["ability-check", "saving-throw", "attack"] : [eff.roll];
|
|
275
|
-
const scopes = (
|
|
305
|
+
const scopes = (_f = normalizeRollScope(eff.scope, rolls[0])) != null ? _f : [eff.scope];
|
|
276
306
|
for (const roll of rolls) for (const scope of scopes)
|
|
277
307
|
out.rollModifiers.push({ mode: eff.mode, roll, scope, condition: eff.condition, label });
|
|
278
308
|
break;
|
|
@@ -282,13 +312,13 @@ function applyEffect(out, eff, label, level) {
|
|
|
282
312
|
ability: eff.ability === "any" ? void 0 : eff.ability,
|
|
283
313
|
on_success: eff.on_success,
|
|
284
314
|
on_failure: eff.on_failure,
|
|
285
|
-
appliesTo: (
|
|
315
|
+
appliesTo: (_g = eff.applies_to) != null ? _g : void 0,
|
|
286
316
|
condition: eff.condition,
|
|
287
317
|
label
|
|
288
318
|
});
|
|
289
319
|
break;
|
|
290
320
|
case "crit-range":
|
|
291
|
-
if (((
|
|
321
|
+
if (((_h = eff.applies_to) != null ? _h : "weapon") !== "spell") out.critRange = Math.min(out.critRange, eff.min_roll);
|
|
292
322
|
break;
|
|
293
323
|
case "extra-attack":
|
|
294
324
|
out.extraAttack = Math.max(out.extraAttack, scaled(eff.count, "count", eff.scales_at, level));
|
|
@@ -300,20 +330,33 @@ function applyEffect(out, eff, label, level) {
|
|
|
300
330
|
if (eff.flag === "no-ranged-in-melee-disadvantage") out.attackNotes.push("No disadvantage firing in melee");
|
|
301
331
|
break;
|
|
302
332
|
case "damage-bonus":
|
|
303
|
-
if (((
|
|
333
|
+
if (((_i = eff.applies_to) != null ? _i : "weapon") !== "spell") {
|
|
304
334
|
const scope = riderScope(eff.applies_to);
|
|
305
335
|
out.damageBonuses.push({
|
|
306
336
|
amount: eff.amount,
|
|
307
337
|
damage_type: eff.damage_type,
|
|
308
338
|
source: label,
|
|
309
339
|
...eff.condition ? { condition: eff.condition } : {},
|
|
310
|
-
...scope ? { scope } : {}
|
|
340
|
+
...scope ? { scope } : {},
|
|
341
|
+
...owner ? { owner } : {}
|
|
342
|
+
});
|
|
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 } : {}
|
|
311
354
|
});
|
|
312
355
|
}
|
|
313
356
|
break;
|
|
314
357
|
case "ability-score-increase":
|
|
315
358
|
if (eff.abilities === "chosen") break;
|
|
316
|
-
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;
|
|
317
360
|
break;
|
|
318
361
|
default:
|
|
319
362
|
break;
|
|
@@ -59,6 +59,18 @@ function normalizeSpellComponents(value) {
|
|
|
59
59
|
if (c.r === true) parts.push("R");
|
|
60
60
|
return parts.join(", ");
|
|
61
61
|
}
|
|
62
|
+
function spellMaterialOf(value) {
|
|
63
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
64
|
+
const m = value.m;
|
|
65
|
+
if (m == null || typeof m !== "object" || Array.isArray(m)) return void 0;
|
|
66
|
+
const { text, cost, consume } = m;
|
|
67
|
+
if (typeof text !== "string") return void 0;
|
|
68
|
+
return {
|
|
69
|
+
text,
|
|
70
|
+
...typeof cost === "number" ? { cost } : {},
|
|
71
|
+
...typeof consume === "boolean" || typeof consume === "string" ? { consume } : {}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
62
74
|
function normalizeSpellDurationEntry(entry) {
|
|
63
75
|
if (entry == null || typeof entry !== "object") return toStringSafe(entry);
|
|
64
76
|
const e = entry;
|
|
@@ -84,9 +96,11 @@ function normalizeSpellDuration(value) {
|
|
|
84
96
|
return value.map((entry) => normalizeSpellDurationEntry(entry)).join("; ");
|
|
85
97
|
}
|
|
86
98
|
function mirrorSpellShapes(entity) {
|
|
99
|
+
const material = spellMaterialOf(entity.components);
|
|
87
100
|
return {
|
|
88
101
|
...entity,
|
|
89
102
|
...entity.components != null ? { components: normalizeSpellComponents(entity.components) } : {},
|
|
103
|
+
...material ? { material } : {},
|
|
90
104
|
...entity.duration != null ? { duration: normalizeSpellDuration(entity.duration) } : {}
|
|
91
105
|
};
|
|
92
106
|
}
|
|
@@ -116,6 +130,8 @@ function parseSpell(source) {
|
|
|
116
130
|
if (raw.range != null) spell.range = toStringSafe(raw.range);
|
|
117
131
|
if (raw.components != null) spell.components = normalizeSpellComponents(raw.components);
|
|
118
132
|
if (raw.duration != null) spell.duration = normalizeSpellDuration(raw.duration);
|
|
133
|
+
const material = spellMaterialOf(raw.components);
|
|
134
|
+
if (material) spell.material = material;
|
|
119
135
|
if (raw.concentration != null) spell.concentration = Boolean(raw.concentration);
|
|
120
136
|
if (raw.ritual != null) spell.ritual = Boolean(raw.ritual);
|
|
121
137
|
if (raw.classes) spell.classes = raw.classes.map(String);
|
|
@@ -158,6 +174,7 @@ function parseSpell(source) {
|
|
|
158
174
|
|
|
159
175
|
export {
|
|
160
176
|
normalizeSpellComponents,
|
|
177
|
+
spellMaterialOf,
|
|
161
178
|
normalizeSpellDuration,
|
|
162
179
|
mirrorSpellShapes,
|
|
163
180
|
parseSpell
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
qualifiedGrantCovers
|
|
3
|
+
} from "./chunk-3LWMFYKS.js";
|
|
1
4
|
import {
|
|
2
5
|
classifyWeaponRange
|
|
3
6
|
} from "./chunk-YDGMBMYI.js";
|
|
7
|
+
import {
|
|
8
|
+
resolveContainment
|
|
9
|
+
} from "./chunk-EJP263OP.js";
|
|
4
10
|
import {
|
|
5
11
|
normKey
|
|
6
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5JXFJ5AU.js";
|
|
7
13
|
import {
|
|
8
14
|
WEAPON_DEFAULT_ACTION_COST,
|
|
9
15
|
resolveEntryEntity
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
resolveContainment
|
|
13
|
-
} from "./chunk-EJP263OP.js";
|
|
16
|
+
} from "./chunk-NXUY5XQN.js";
|
|
14
17
|
import {
|
|
15
18
|
readNumericBonus
|
|
16
19
|
} from "./chunk-HHBD4SQ6.js";
|
|
@@ -61,6 +64,7 @@ function emptyAppliedBonuses() {
|
|
|
61
64
|
ability_bonuses: {},
|
|
62
65
|
ability_statics: {},
|
|
63
66
|
save_bonus: 0,
|
|
67
|
+
save_terms: [],
|
|
64
68
|
speed_bonuses: { walk: 0, fly: null, swim: 0, climb: 0 },
|
|
65
69
|
spell_attack: 0,
|
|
66
70
|
spell_save_dc: 0,
|
|
@@ -103,7 +107,7 @@ function pushApply(outcome, field, source, pool, onApply) {
|
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
function computeAppliedBonuses(resolved, _profs, registry, warnings) {
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
110
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
107
111
|
const out = emptyAppliedBonuses();
|
|
108
112
|
const equipment = (_a = resolved.definition.equipment) != null ? _a : [];
|
|
109
113
|
const ctx = buildConditionContext(resolved, {}, registry);
|
|
@@ -135,13 +139,15 @@ function computeAppliedBonuses(resolved, _profs, registry, warnings) {
|
|
|
135
139
|
}
|
|
136
140
|
const b = item.bonuses;
|
|
137
141
|
if (!b) continue;
|
|
142
|
+
const saveSource = (_q = (_p = entry.overrides) == null ? void 0 : _p.name) != null ? _q : item.name;
|
|
138
143
|
pushApply(
|
|
139
144
|
readNumericBonus(b.saving_throws, ctx),
|
|
140
145
|
"saving_throws",
|
|
141
|
-
|
|
146
|
+
saveSource,
|
|
142
147
|
out.informational,
|
|
143
148
|
(v) => {
|
|
144
149
|
out.save_bonus += v;
|
|
150
|
+
out.save_terms.push({ source: saveSource, amount: v });
|
|
145
151
|
}
|
|
146
152
|
);
|
|
147
153
|
pushApply(
|
|
@@ -162,7 +168,7 @@ function computeAppliedBonuses(resolved, _profs, registry, warnings) {
|
|
|
162
168
|
out.spell_save_dc += v;
|
|
163
169
|
}
|
|
164
170
|
);
|
|
165
|
-
if ((
|
|
171
|
+
if ((_r = b.ability_scores) == null ? void 0 : _r.bonus) {
|
|
166
172
|
for (const [k, v] of Object.entries(b.ability_scores.bonus)) {
|
|
167
173
|
if (!isAbilityKey(k)) continue;
|
|
168
174
|
pushApply(
|
|
@@ -177,7 +183,7 @@ function computeAppliedBonuses(resolved, _profs, registry, warnings) {
|
|
|
177
183
|
);
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
|
-
if ((
|
|
186
|
+
if ((_s = b.ability_scores) == null ? void 0 : _s.static) {
|
|
181
187
|
for (const [k, n] of Object.entries(b.ability_scores.static)) {
|
|
182
188
|
if (!isAbilityKey(k) || typeof n !== "number") continue;
|
|
183
189
|
const prev = out.ability_statics[k];
|
|
@@ -411,6 +417,7 @@ function attackAbility(weapon, mods, weaponAbilities) {
|
|
|
411
417
|
function isWeaponSlugProficient(weapon, weaponSlug, profs) {
|
|
412
418
|
const wp = profs.weapons;
|
|
413
419
|
if (wp.specific.some((e) => e === weaponSlug || normKey(e) === normKey(weapon.name))) return true;
|
|
420
|
+
if (wp.specific.some((e) => qualifiedGrantCovers(e, weapon))) return true;
|
|
414
421
|
const cat = weapon.category;
|
|
415
422
|
if (typeof cat === "string") {
|
|
416
423
|
if (/^simple\b/.test(cat) && wp.categories.includes("simple")) return true;
|
|
@@ -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";
|
|
@@ -24,11 +24,9 @@ function derivePoolLayout(entries) {
|
|
|
24
24
|
}
|
|
25
25
|
return tied ? void 0 : best;
|
|
26
26
|
}
|
|
27
|
-
var DEFAULT_POOL_ROWS = "blocks";
|
|
28
27
|
function poolPresentation(authored, derived) {
|
|
29
28
|
const head = authored === "point-pool" ? "points" : authored === "dice-pool" ? "dice" : derived === "point-pool" ? "points" : "dice";
|
|
30
|
-
|
|
31
|
-
return { head, rows };
|
|
29
|
+
return { head };
|
|
32
30
|
}
|
|
33
31
|
var RENDERING_HINT_AFFORDANCE = {
|
|
34
32
|
"granted-die-to-ally": "granted-die"
|
|
@@ -49,7 +47,6 @@ function formatAffordanceCaption(affordance, values) {
|
|
|
49
47
|
export {
|
|
50
48
|
RENDERING_HINT_LAYOUT,
|
|
51
49
|
derivePoolLayout,
|
|
52
|
-
DEFAULT_POOL_ROWS,
|
|
53
50
|
poolPresentation,
|
|
54
51
|
RENDERING_HINT_AFFORDANCE,
|
|
55
52
|
deriveEntryAffordance,
|