@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,34 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
qualifiedGrantCovers
|
|
3
|
+
} from "../chunk-3LWMFYKS.js";
|
|
4
|
+
import "../chunk-YDGMBMYI.js";
|
|
1
5
|
import {
|
|
2
6
|
collectChosenProficiencies,
|
|
3
7
|
collectProficiencyGrants,
|
|
4
|
-
computeEffectiveProficiencies
|
|
5
|
-
|
|
8
|
+
computeEffectiveProficiencies,
|
|
9
|
+
computeSuppressedProficiencies
|
|
10
|
+
} from "../chunk-EJD47JHL.js";
|
|
6
11
|
import "../chunk-2LULMQTF.js";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-QA3YCOML.js";
|
|
13
|
+
import "../chunk-64VNLMSG.js";
|
|
9
14
|
import "../chunk-TOM66P2P.js";
|
|
10
15
|
import "../chunk-KU3YLF6D.js";
|
|
11
|
-
import
|
|
16
|
+
import {
|
|
17
|
+
normKey,
|
|
18
|
+
proficiencyKey,
|
|
19
|
+
proficiencyLabel,
|
|
20
|
+
toProfSlug,
|
|
21
|
+
weaponProfKey
|
|
22
|
+
} from "../chunk-5JXFJ5AU.js";
|
|
23
|
+
import "../chunk-RD2MID3M.js";
|
|
24
|
+
import "../chunk-LICYHPI3.js";
|
|
25
|
+
import "../chunk-PVCEA4HZ.js";
|
|
12
26
|
import "../chunk-KSTV7J2U.js";
|
|
13
27
|
import "../chunk-DPUJDOKV.js";
|
|
14
28
|
import "../chunk-LBEXLN6I.js";
|
|
15
|
-
import
|
|
16
|
-
proficiencyLabel,
|
|
17
|
-
toProfSlug
|
|
18
|
-
} from "../chunk-RLGQ5PZZ.js";
|
|
19
|
-
import "../chunk-3VZZDKRA.js";
|
|
29
|
+
import "../chunk-NXUY5XQN.js";
|
|
20
30
|
import "../chunk-W6GC6OKK.js";
|
|
21
31
|
import "../chunk-B3DP42OM.js";
|
|
22
32
|
import "../chunk-IUAAXXNO.js";
|
|
23
33
|
import "../chunk-YHYTW5QA.js";
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-PVCEA4HZ.js";
|
|
34
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
26
35
|
import "../chunk-IHE6KVC3.js";
|
|
27
36
|
import "../chunk-LHZXYFBU.js";
|
|
28
37
|
import "../chunk-YBLDE5CG.js";
|
|
29
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
30
38
|
import "../chunk-LVQLWRCU.js";
|
|
31
39
|
import "../chunk-CM5CWO4K.js";
|
|
40
|
+
import "../chunk-4J6DS3EJ.js";
|
|
32
41
|
import "../chunk-EVMUJYUD.js";
|
|
33
42
|
import "../chunk-VTTA2ALZ.js";
|
|
34
43
|
import "../chunk-ZCTUYGNV.js";
|
|
@@ -52,8 +61,29 @@ function collectProficiencySources(resolved) {
|
|
|
52
61
|
};
|
|
53
62
|
}
|
|
54
63
|
function aggregateProficiencies(resolved) {
|
|
55
|
-
const
|
|
64
|
+
const { armor, weapons } = composeArmorWeapons(resolved);
|
|
56
65
|
const effective = computeEffectiveProficiencies(resolved);
|
|
66
|
+
return { armor: armor.kept, weapons: weapons.kept, tools: effective.tools, languages: effective.languages };
|
|
67
|
+
}
|
|
68
|
+
function proficiencyOverview(resolved, kind) {
|
|
69
|
+
if (kind === "armor" || kind === "weapons") {
|
|
70
|
+
const c = composeArmorWeapons(resolved)[kind];
|
|
71
|
+
return { effective: c.kept, removed: c.suppressed };
|
|
72
|
+
}
|
|
73
|
+
return { effective: computeEffectiveProficiencies(resolved)[kind], removed: computeSuppressedProficiencies(resolved)[kind] };
|
|
74
|
+
}
|
|
75
|
+
function weaponCoveredBy(effective, weapon) {
|
|
76
|
+
const cat = typeof weapon.category === "string" ? weapon.category : "";
|
|
77
|
+
const base = cat.split("-")[0];
|
|
78
|
+
return effective.find((e) => {
|
|
79
|
+
const key = weaponProfKey(e.value);
|
|
80
|
+
if ((key === "simple" || key === "martial") && key === base) return true;
|
|
81
|
+
if (cat && key === normKey(cat)) return true;
|
|
82
|
+
return qualifiedGrantCovers(e.value, weapon);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function composeArmorWeapons(resolved) {
|
|
86
|
+
const src = collectProficiencySources(resolved);
|
|
57
87
|
return {
|
|
58
88
|
// Walk order defines `sources` order (spec §4.1): class before feats, and
|
|
59
89
|
// for weapons the class `fixed` names before the class categories, matching
|
|
@@ -68,10 +98,27 @@ function aggregateProficiencies(resolved) {
|
|
|
68
98
|
// keeps origin `grant` and its granting source(s) (R4-G3b §7 F5 · the same
|
|
69
99
|
// grants-then-picks order computeEffectiveProficiencies uses for the
|
|
70
100
|
// language and tool buckets). Armor passes none.
|
|
71
|
-
armor: composeGrantEntries([src.classArmor, src.featArmor, src.effectArmor]),
|
|
72
|
-
weapons:
|
|
73
|
-
|
|
74
|
-
|
|
101
|
+
armor: applyKindOverrides(resolved, "armor", composeGrantEntries([src.classArmor, src.featArmor, src.effectArmor])),
|
|
102
|
+
weapons: applyKindOverrides(
|
|
103
|
+
resolved,
|
|
104
|
+
"weapons",
|
|
105
|
+
composeGrantEntries([src.classWeaponFixed, src.classWeaponCategories, src.featWeapons, src.effectWeapons], src.chosenWeapons)
|
|
106
|
+
)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function applyKindOverrides(resolved, kind, entries) {
|
|
110
|
+
var _a, _b, _c, _d;
|
|
111
|
+
const ov = (_b = (_a = resolved.definition) == null ? void 0 : _a.overrides) == null ? void 0 : _b[kind];
|
|
112
|
+
const key = (v) => proficiencyKey(kind, v);
|
|
113
|
+
const all = [...entries];
|
|
114
|
+
for (const v of (_c = ov == null ? void 0 : ov.add) != null ? _c : []) {
|
|
115
|
+
if (!all.some((e) => key(e.value) === key(v))) all.push({ value: v, label: prettyName(v), sources: [], origin: "manual" });
|
|
116
|
+
}
|
|
117
|
+
const removes = new Set(((_d = ov == null ? void 0 : ov.remove) != null ? _d : []).map(key));
|
|
118
|
+
const byLabel = (a, b) => a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
|
|
119
|
+
return {
|
|
120
|
+
kept: all.filter((e) => !removes.has(key(e.value))).sort(byLabel),
|
|
121
|
+
suppressed: all.filter((e) => removes.has(key(e.value))).sort(byLabel)
|
|
75
122
|
};
|
|
76
123
|
}
|
|
77
124
|
function composeGrantEntries(buckets, picks = []) {
|
|
@@ -103,5 +150,7 @@ function prettyName(slug) {
|
|
|
103
150
|
}
|
|
104
151
|
export {
|
|
105
152
|
aggregateProficiencies,
|
|
106
|
-
collectProficiencySources
|
|
153
|
+
collectProficiencySources,
|
|
154
|
+
proficiencyOverview,
|
|
155
|
+
weaponCoveredBy
|
|
107
156
|
};
|
|
@@ -27,3 +27,17 @@ export declare const humanizeProficiency: (s: string) => string;
|
|
|
27
27
|
* the first character capitalised, every other letter untouched. Title-casing it word by word lower-cased
|
|
28
28
|
* `2H` to `2h` and read "That Have The Light Property". */
|
|
29
29
|
export declare const proficiencyLabel: (raw: string) => string;
|
|
30
|
+
/** The four proficiency kinds the sheet lists and the D4 pickers edit, one picker per kind. */
|
|
31
|
+
export type ProficiencyKind = "armor" | "weapons" | "tools" | "languages";
|
|
32
|
+
/** D4 A: the key of a WEAPON proficiency value, so every spelling of one grant folds onto one key. A category reads
|
|
33
|
+
* `simple` or `martial` whatever its spelling ("martial", "Martial weapons"); anything else is keyed by
|
|
34
|
+
* {@link normKey}, the rule the live weapon gate (`isWeaponSlugProficient`) matches a weapon's name by, so
|
|
35
|
+
* "longswords", "Longsword" and "longsword" meet, and "hand-crossbow" meets "Hand Crossbows" and "Crossbow, hand". */
|
|
36
|
+
export declare const weaponProfKey: (raw: string) => string;
|
|
37
|
+
/** D4 A: the key of an ARMOR proficiency value: `light`, `medium`, `heavy`, `shield` whatever the spelling
|
|
38
|
+
* ("Heavy armor", "shields"). */
|
|
39
|
+
export declare const armorProfKey: (raw: string) => string;
|
|
40
|
+
/** D4 A: the one comparison key per kind, used by the engine's override readers and the plugin's writers alike, so a
|
|
41
|
+
* value the writer stores and the value the reader suppresses always meet. Languages and tools keep `toProfSlug`,
|
|
42
|
+
* unchanged. */
|
|
43
|
+
export declare const proficiencyKey: (kind: ProficiencyKind, raw: string) => string;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
+
armorProfKey,
|
|
2
3
|
humanizeProficiency,
|
|
3
4
|
normKey,
|
|
5
|
+
proficiencyKey,
|
|
4
6
|
proficiencyLabel,
|
|
5
|
-
toProfSlug
|
|
6
|
-
|
|
7
|
+
toProfSlug,
|
|
8
|
+
weaponProfKey
|
|
9
|
+
} from "../chunk-5JXFJ5AU.js";
|
|
7
10
|
export {
|
|
11
|
+
armorProfKey,
|
|
8
12
|
humanizeProficiency,
|
|
9
13
|
normKey,
|
|
14
|
+
proficiencyKey,
|
|
10
15
|
proficiencyLabel,
|
|
11
|
-
toProfSlug
|
|
16
|
+
toProfSlug,
|
|
17
|
+
weaponProfKey
|
|
12
18
|
};
|
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -1,28 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildUnarmedRow,
|
|
3
|
+
computeAppliedBonuses,
|
|
4
|
+
computeSlotsAndAttacks,
|
|
5
|
+
emptyAppliedBonuses
|
|
6
|
+
} from "../chunk-7XJHI5H5.js";
|
|
7
|
+
import "../chunk-3LWMFYKS.js";
|
|
8
|
+
import "../chunk-YDGMBMYI.js";
|
|
1
9
|
import {
|
|
2
10
|
amountBindingsFor
|
|
3
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-TRBGC4ZG.js";
|
|
4
12
|
import "../chunk-KR6JF3BF.js";
|
|
5
13
|
import {
|
|
6
14
|
computeConditionEffects
|
|
7
15
|
} from "../chunk-MYY2C5MB.js";
|
|
16
|
+
import "../chunk-EJP263OP.js";
|
|
8
17
|
import {
|
|
9
18
|
collectChosenAbilityPoints,
|
|
10
19
|
collectChosenProficiencies
|
|
11
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-EJD47JHL.js";
|
|
12
21
|
import "../chunk-2LULMQTF.js";
|
|
13
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-QA3YCOML.js";
|
|
14
23
|
import {
|
|
15
24
|
assembleEffectFeatures,
|
|
16
25
|
computeFeatureEffects,
|
|
17
26
|
foldsNow,
|
|
18
27
|
selfEffectsOf
|
|
19
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-64VNLMSG.js";
|
|
20
29
|
import "../chunk-TOM66P2P.js";
|
|
21
30
|
import "../chunk-KU3YLF6D.js";
|
|
31
|
+
import {
|
|
32
|
+
proficiencyKey
|
|
33
|
+
} from "../chunk-5JXFJ5AU.js";
|
|
22
34
|
import {
|
|
23
35
|
featPickSites,
|
|
24
|
-
poolMemberSitesOf
|
|
25
|
-
|
|
36
|
+
poolMemberSitesOf,
|
|
37
|
+
spellsReached
|
|
38
|
+
} from "../chunk-RD2MID3M.js";
|
|
39
|
+
import "../chunk-LICYHPI3.js";
|
|
40
|
+
import "../chunk-PVCEA4HZ.js";
|
|
26
41
|
import {
|
|
27
42
|
resourceLevelFor
|
|
28
43
|
} from "../chunk-KSTV7J2U.js";
|
|
@@ -38,17 +53,7 @@ import {
|
|
|
38
53
|
import {
|
|
39
54
|
toDefenseSlug
|
|
40
55
|
} from "../chunk-XJ2F2WO6.js";
|
|
41
|
-
import
|
|
42
|
-
buildUnarmedRow,
|
|
43
|
-
computeAppliedBonuses,
|
|
44
|
-
computeSlotsAndAttacks,
|
|
45
|
-
emptyAppliedBonuses
|
|
46
|
-
} from "../chunk-JSM6JFZR.js";
|
|
47
|
-
import "../chunk-3LWMFYKS.js";
|
|
48
|
-
import "../chunk-YDGMBMYI.js";
|
|
49
|
-
import "../chunk-EJP263OP.js";
|
|
50
|
-
import "../chunk-RLGQ5PZZ.js";
|
|
51
|
-
import "../chunk-3VZZDKRA.js";
|
|
56
|
+
import "../chunk-NXUY5XQN.js";
|
|
52
57
|
import "../chunk-W6GC6OKK.js";
|
|
53
58
|
import "../chunk-B3DP42OM.js";
|
|
54
59
|
import {
|
|
@@ -56,22 +61,24 @@ import {
|
|
|
56
61
|
unarmedDieColumnFor
|
|
57
62
|
} from "../chunk-IUAAXXNO.js";
|
|
58
63
|
import "../chunk-YHYTW5QA.js";
|
|
59
|
-
import "../chunk-
|
|
60
|
-
import "../chunk-PVCEA4HZ.js";
|
|
64
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
61
65
|
import "../chunk-IHE6KVC3.js";
|
|
62
66
|
import "../chunk-HHBD4SQ6.js";
|
|
63
67
|
import "../chunk-A54HHCWW.js";
|
|
64
68
|
import "../chunk-LHZXYFBU.js";
|
|
65
69
|
import "../chunk-YBLDE5CG.js";
|
|
66
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
67
70
|
import "../chunk-LVQLWRCU.js";
|
|
68
71
|
import "../chunk-CM5CWO4K.js";
|
|
72
|
+
import "../chunk-4J6DS3EJ.js";
|
|
69
73
|
import {
|
|
70
74
|
resolveAmountText
|
|
71
|
-
} from "../chunk-
|
|
75
|
+
} from "../chunk-WOHX7YTH.js";
|
|
72
76
|
import "../chunk-EVMUJYUD.js";
|
|
73
77
|
import "../chunk-VTTA2ALZ.js";
|
|
74
|
-
import
|
|
78
|
+
import {
|
|
79
|
+
bareEntitySlug,
|
|
80
|
+
slugify
|
|
81
|
+
} from "../chunk-ZCTUYGNV.js";
|
|
75
82
|
import "../chunk-7Q2VPKCD.js";
|
|
76
83
|
import "../chunk-ZDAEGJH4.js";
|
|
77
84
|
import "../chunk-3TM34RSJ.js";
|
|
@@ -93,6 +100,60 @@ import {
|
|
|
93
100
|
import "../chunk-4U55VNC7.js";
|
|
94
101
|
import "../chunk-UA5KS2PL.js";
|
|
95
102
|
|
|
103
|
+
// src/pc/pc.spell-scope.ts
|
|
104
|
+
var lower = (s) => (s != null ? s : "").trim().toLowerCase();
|
|
105
|
+
function namedSpellSlug(ref) {
|
|
106
|
+
var _a;
|
|
107
|
+
const inner = ref.replace(/^\[\[/, "").replace(/\]\]$/, "").split("|")[0];
|
|
108
|
+
return slugify((_a = inner.split("/").pop()) != null ? _a : inner);
|
|
109
|
+
}
|
|
110
|
+
function dealsDamage(spell) {
|
|
111
|
+
var _a, _b;
|
|
112
|
+
return ((_b = (_a = spell.damage) == null ? void 0 : _a.types) != null ? _b : []).some((t) => t.trim() !== "");
|
|
113
|
+
}
|
|
114
|
+
function spellsInScope(scope, spells, pickedTypes) {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
if (!scope) return [];
|
|
117
|
+
const picked = scope.damage_type_pick !== void 0 ? pickedTypes(scope.damage_type_pick).map(lower) : null;
|
|
118
|
+
const types = (_a = scope.damage_types) == null ? void 0 : _a.map(lower);
|
|
119
|
+
const named = (_b = scope.spells) == null ? void 0 : _b.map(namedSpellSlug);
|
|
120
|
+
const hit = spells.filter(({ slug, entity: e }) => {
|
|
121
|
+
var _a2, _b2, _c, _d, _e;
|
|
122
|
+
if (!dealsDamage(e)) return false;
|
|
123
|
+
const own = ((_b2 = (_a2 = e.damage) == null ? void 0 : _a2.types) != null ? _b2 : []).map(lower);
|
|
124
|
+
if (scope.list !== void 0 && !((_c = e.classes) != null ? _c : []).map(lower).includes(lower(scope.list))) return false;
|
|
125
|
+
if (scope.level !== void 0 && ((_d = e.level) != null ? _d : 0) !== scope.level) return false;
|
|
126
|
+
if (scope.school !== void 0 && lower(e.school) !== lower(scope.school)) return false;
|
|
127
|
+
if (types && !own.some((t) => types.includes(t))) return false;
|
|
128
|
+
if (picked && !own.some((t) => picked.includes(t))) return false;
|
|
129
|
+
if (named && !named.includes(bareEntitySlug(slug)) && !named.includes(slugify((_e = e.name) != null ? _e : ""))) return false;
|
|
130
|
+
return true;
|
|
131
|
+
});
|
|
132
|
+
return [...new Set(hit.map((s) => s.slug))];
|
|
133
|
+
}
|
|
134
|
+
function pickedDamageTypes(resolved, choiceId) {
|
|
135
|
+
var _a, _b, _c, _d, _e, _f;
|
|
136
|
+
const out = /* @__PURE__ */ new Set();
|
|
137
|
+
for (const c of (_a = resolved.classes) != null ? _a : []) {
|
|
138
|
+
for (const owner of [c.entity, c.subclass]) {
|
|
139
|
+
for (const [lvl, feats] of Object.entries((_b = owner == null ? void 0 : owner.features_by_level) != null ? _b : {})) {
|
|
140
|
+
for (const feat of feats != null ? feats : []) {
|
|
141
|
+
for (const ch of (_c = feat.choices) != null ? _c : []) {
|
|
142
|
+
if (ch.kind !== "select-inline" || ch.id !== choiceId) continue;
|
|
143
|
+
const sel = ((_e = (_d = c.choices) == null ? void 0 : _d[Number(lvl)]) != null ? _e : {})[ch.id];
|
|
144
|
+
if (typeof sel !== "string") continue;
|
|
145
|
+
const opt = ch.options.find((o) => o.value === sel);
|
|
146
|
+
for (const word of `${sel} ${(_f = opt == null ? void 0 : opt.label) != null ? _f : ""}`.split(/[^A-Za-z]+/)) {
|
|
147
|
+
if (word && isCanonicalDamageType(word)) out.add(word.toLowerCase());
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return [...out];
|
|
155
|
+
}
|
|
156
|
+
|
|
96
157
|
// src/pc/pc.recalc.ts
|
|
97
158
|
var WEAPON_CATEGORY_WORDS = /* @__PURE__ */ new Set([
|
|
98
159
|
"simple",
|
|
@@ -453,6 +514,25 @@ function mergeInto(target, source) {
|
|
|
453
514
|
for (const c of source.categories) if (!target.categories.includes(c)) target.categories.push(c);
|
|
454
515
|
for (const s of source.specific) if (!target.specific.includes(s)) target.specific.push(s);
|
|
455
516
|
}
|
|
517
|
+
function applyArmorWeaponOverrides(profs, overrides) {
|
|
518
|
+
var _a, _b;
|
|
519
|
+
for (const kind of ["armor", "weapons"]) {
|
|
520
|
+
const ov = overrides == null ? void 0 : overrides[kind];
|
|
521
|
+
if (!ov) continue;
|
|
522
|
+
const set = profs[kind];
|
|
523
|
+
const key = (v) => proficiencyKey(kind, v);
|
|
524
|
+
const removes = new Set(((_a = ov.remove) != null ? _a : []).map(key));
|
|
525
|
+
for (const v of (_b = ov.add) != null ? _b : []) {
|
|
526
|
+
const k = key(v);
|
|
527
|
+
if (removes.has(k)) continue;
|
|
528
|
+
const category = kind === "armor" || k === "simple" || k === "martial";
|
|
529
|
+
const target = category ? set.categories : set.specific;
|
|
530
|
+
if (!target.some((e) => key(e) === k)) target.push(category ? k : v);
|
|
531
|
+
}
|
|
532
|
+
set.categories = set.categories.filter((e) => !removes.has(key(e)));
|
|
533
|
+
set.specific = set.specific.filter((e) => !removes.has(key(e)));
|
|
534
|
+
}
|
|
535
|
+
}
|
|
456
536
|
var ORIGIN_RANK = { manual: 0, equipment: 1, grant: 2 };
|
|
457
537
|
function composeDefenseEntries(manual, equipment, grants) {
|
|
458
538
|
var _a;
|
|
@@ -544,7 +624,7 @@ function computeProficiencies(resolved) {
|
|
|
544
624
|
};
|
|
545
625
|
}
|
|
546
626
|
function recalc(resolved, registry) {
|
|
547
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z
|
|
627
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$;
|
|
548
628
|
const warnings = [];
|
|
549
629
|
const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
|
|
550
630
|
const chosenProfs = collectChosenProficiencies(resolved);
|
|
@@ -587,6 +667,7 @@ function recalc(resolved, registry) {
|
|
|
587
667
|
}
|
|
588
668
|
}
|
|
589
669
|
profsForApply.languages.sort();
|
|
670
|
+
applyArmorWeaponOverrides(profsForApply, (_b = resolved.definition) == null ? void 0 : _b.overrides);
|
|
590
671
|
const applied = registry ? computeAppliedBonuses(resolved, profsForApply, registry, warnings) : emptyAppliedBonuses();
|
|
591
672
|
const savesInformational = applied.informational.filter(
|
|
592
673
|
(i) => i.field === "saving_throws"
|
|
@@ -601,7 +682,7 @@ function recalc(resolved, registry) {
|
|
|
601
682
|
const scores = { ...baseScores };
|
|
602
683
|
for (const ab of ABILITY_KEYS) {
|
|
603
684
|
const bonus = applied.ability_bonuses[ab];
|
|
604
|
-
scores[ab] += (typeof bonus === "number" ? bonus : 0) + ((
|
|
685
|
+
scores[ab] += (typeof bonus === "number" ? bonus : 0) + ((_c = featureEffects.ability_bonus[ab]) != null ? _c : 0);
|
|
605
686
|
}
|
|
606
687
|
for (const ab of ABILITY_KEYS) {
|
|
607
688
|
const stat = applied.ability_statics[ab];
|
|
@@ -628,8 +709,8 @@ function recalc(resolved, registry) {
|
|
|
628
709
|
resolved.definition.edition,
|
|
629
710
|
scores
|
|
630
711
|
);
|
|
631
|
-
const firstClass = (
|
|
632
|
-
const saveProfs = new Set((
|
|
712
|
+
const firstClass = (_e = (_d = resolved.classes[0]) == null ? void 0 : _d.entity) != null ? _e : null;
|
|
713
|
+
const saveProfs = new Set((_f = firstClass == null ? void 0 : firstClass.saving_throws) != null ? _f : []);
|
|
633
714
|
for (const ab of featureEffects.proficiencies.saves) saveProfs.add(ab);
|
|
634
715
|
for (const ab of chosenProfs.saves) saveProfs.add(ab);
|
|
635
716
|
const saves = {};
|
|
@@ -639,8 +720,8 @@ function recalc(resolved, registry) {
|
|
|
639
720
|
return t.inactiveWhile === "incapacitated" ? !conditionEffects.actions_disabled : t.inactiveWhile === "unconscious" ? !((_a2 = resolved.state.conditions) != null ? _a2 : []).includes("unconscious") : true;
|
|
640
721
|
});
|
|
641
722
|
for (const ab of ABILITY_KEYS) {
|
|
642
|
-
const override = (
|
|
643
|
-
const prof = (
|
|
723
|
+
const override = (_g = overrides.saves) == null ? void 0 : _g[ab];
|
|
724
|
+
const prof = (_h = override == null ? void 0 : override.proficient) != null ? _h : saveProfs.has(ab);
|
|
644
725
|
const featureTerms = [];
|
|
645
726
|
for (const t of activeSaveBonusTerms) {
|
|
646
727
|
if (t.saves.length > 0 && !t.saves.includes(ab)) continue;
|
|
@@ -650,7 +731,7 @@ function recalc(resolved, registry) {
|
|
|
650
731
|
else if (amount > prior.amount) prior.amount = amount;
|
|
651
732
|
}
|
|
652
733
|
const derivedBonus = savingThrow(scores[ab], prof, proficiencyBonus) + applied.save_bonus + featureTerms.reduce((sum, t) => sum + t.amount, 0) + conditionEffects.d20_test_penalty;
|
|
653
|
-
const bonus = (
|
|
734
|
+
const bonus = (_i = override == null ? void 0 : override.bonus) != null ? _i : derivedBonus;
|
|
654
735
|
saves[ab] = { bonus, proficient: prof };
|
|
655
736
|
saveBreakdowns[ab] = [
|
|
656
737
|
{ source: ab.toUpperCase(), amount: mods[ab] },
|
|
@@ -662,7 +743,7 @@ function recalc(resolved, registry) {
|
|
|
662
743
|
}
|
|
663
744
|
const profSet = /* @__PURE__ */ new Set([
|
|
664
745
|
...resolved.definition.skills.proficient,
|
|
665
|
-
...(
|
|
746
|
+
...(_k = (_j = resolved.background) == null ? void 0 : _j.skill_proficiencies) != null ? _k : [],
|
|
666
747
|
...chosenProfs.skills,
|
|
667
748
|
...featureEffects.proficiencies.skills
|
|
668
749
|
]);
|
|
@@ -672,12 +753,12 @@ function recalc(resolved, registry) {
|
|
|
672
753
|
for (const skill of ALL_SKILLS) {
|
|
673
754
|
const skillKey = skillSlugFromDisplay(skill);
|
|
674
755
|
const ab = SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];
|
|
675
|
-
const override = (
|
|
676
|
-
const tri = (
|
|
756
|
+
const override = (_l = overrides.skills) == null ? void 0 : _l[skillKey];
|
|
757
|
+
const tri = (_m = override == null ? void 0 : override.proficiency) != null ? _m : expSet.has(skillKey) ? "expertise" : profSet.has(skillKey) ? "proficient" : "none";
|
|
677
758
|
const skillTerms = featureEffects.skill_bonus_terms.filter((t) => t.skills.includes(skillKey)).map((t) => ({ source: t.label, amount: Math.max(t.minimum, mods[t.ability]) }));
|
|
678
759
|
const halfProfTerms = tri !== "none" ? [] : featureEffects.half_proficiency_terms.filter((t) => t.skills.length === 0 || t.skills.includes(skillKey)).map((t) => ({ source: t.label, amount: t.round === "up" ? Math.ceil(proficiencyBonus / 2) : Math.floor(proficiencyBonus / 2) }));
|
|
679
760
|
const halfProfBest = halfProfTerms.length ? halfProfTerms.reduce((best, t) => t.amount > best.amount ? t : best) : null;
|
|
680
|
-
const bonus = (
|
|
761
|
+
const bonus = (_o = override == null ? void 0 : override.bonus) != null ? _o : skillBonus(scores[ab], tri, proficiencyBonus) + skillTerms.reduce((sum, t) => sum + t.amount, 0) + ((_n = halfProfBest == null ? void 0 : halfProfBest.amount) != null ? _n : 0) + conditionEffects.d20_test_penalty;
|
|
681
762
|
skillBreakdowns[skillKey] = [
|
|
682
763
|
{ source: ab.toUpperCase(), amount: mods[ab] },
|
|
683
764
|
...tri !== "none" ? [{ source: tri === "expertise" ? "Expertise" : "Proficiency", amount: proficiencyBonus * (tri === "expertise" ? 2 : 1) }] : [],
|
|
@@ -693,12 +774,12 @@ function recalc(resolved, registry) {
|
|
|
693
774
|
};
|
|
694
775
|
}
|
|
695
776
|
const passives = {
|
|
696
|
-
perception: (
|
|
697
|
-
investigation: (
|
|
698
|
-
insight: (
|
|
777
|
+
perception: (_q = (_p = overrides.passives) == null ? void 0 : _p.perception) != null ? _q : 10 + skills.perception.bonus,
|
|
778
|
+
investigation: (_s = (_r = overrides.passives) == null ? void 0 : _r.investigation) != null ? _s : 10 + skills.investigation.bonus,
|
|
779
|
+
insight: (_u = (_t = overrides.passives) == null ? void 0 : _t.insight) != null ? _u : 10 + skills.insight.bonus
|
|
699
780
|
};
|
|
700
|
-
const hpRolled = (
|
|
701
|
-
const hpModifier = (
|
|
781
|
+
const hpRolled = (_w = (_v = overrides.hp) == null ? void 0 : _v.rolled) != null ? _w : null;
|
|
782
|
+
const hpModifier = (_y = (_x = overrides.hp) == null ? void 0 : _x.modifier) != null ? _y : null;
|
|
702
783
|
const averageDiceSum = hitDiceAverageSum(resolved.classes);
|
|
703
784
|
const conLevels = hpLevelCount(resolved.classes);
|
|
704
785
|
const diceSum = hpRolled != null ? hpRolled : averageDiceSum;
|
|
@@ -706,7 +787,7 @@ function recalc(resolved, registry) {
|
|
|
706
787
|
const diceConClamped = Math.max(1, diceConRaw);
|
|
707
788
|
const hpMaxDerived = diceConClamped + featureEffects.hp_per_level_bonus * totalLevel + (hpModifier != null ? hpModifier : 0);
|
|
708
789
|
const hpMaxAfterConditions = Math.max(0, Math.floor(hpMaxDerived * conditionEffects.hp_max_multiplier));
|
|
709
|
-
const hpMax = (
|
|
790
|
+
const hpMax = (_A = (_z = overrides.hp) == null ? void 0 : _z.max) != null ? _A : hpMaxAfterConditions;
|
|
710
791
|
const hpBreakdown = {
|
|
711
792
|
diceSum,
|
|
712
793
|
diceSource: hpRolled != null ? "rolled" : "average",
|
|
@@ -724,7 +805,7 @@ function recalc(resolved, registry) {
|
|
|
724
805
|
exhaustionMultiplier: conditionEffects.hp_max_multiplier,
|
|
725
806
|
exhaustionLevel: conditionEffects.exhaustion_level,
|
|
726
807
|
derivedMax: hpMaxAfterConditions,
|
|
727
|
-
override: (
|
|
808
|
+
override: (_C = (_B = overrides.hp) == null ? void 0 : _B.max) != null ? _C : null,
|
|
728
809
|
final: hpMax
|
|
729
810
|
};
|
|
730
811
|
const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature", condition: t.condition }));
|
|
@@ -748,7 +829,7 @@ function recalc(resolved, registry) {
|
|
|
748
829
|
let acBreakdownDerived = [];
|
|
749
830
|
let acInformationalDerived = [];
|
|
750
831
|
if (registry) {
|
|
751
|
-
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (
|
|
832
|
+
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (_D = resolved.weaponMasteries) != null ? _D : [], featureEffects.attunement_set);
|
|
752
833
|
if (derivedEquipment.equippedSlots.armor) {
|
|
753
834
|
const featTerms = featureAcTermsFor(true);
|
|
754
835
|
acDerived = derivedEquipment.ac + sumTerms(featTerms);
|
|
@@ -772,13 +853,13 @@ function recalc(resolved, registry) {
|
|
|
772
853
|
acDerived = total + sumTerms(featTerms);
|
|
773
854
|
acBreakdownDerived = [...terms, ...featTerms];
|
|
774
855
|
}
|
|
775
|
-
const ac = (
|
|
856
|
+
const ac = (_E = overrides.ac) != null ? _E : acDerived;
|
|
776
857
|
const additiveSpeed = speedFromRace(resolved) + applied.speed_bonuses.walk + featureEffects.speed_walk_bonus;
|
|
777
858
|
const baseSpeed = Math.max(featureEffects.speed_walk_set, additiveSpeed);
|
|
778
859
|
const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
|
|
779
860
|
const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
|
|
780
|
-
const speed = (
|
|
781
|
-
const raceSpeed = (
|
|
861
|
+
const speed = (_F = overrides.speed) != null ? _F : conditionSpeed;
|
|
862
|
+
const raceSpeed = (_I = (_H = (_G = resolved.race) == null ? void 0 : _G.speed) == null ? void 0 : _H.walk) != null ? _I : 30;
|
|
782
863
|
const speedBreakdown = [
|
|
783
864
|
{ source: "Base speed", amount: raceSpeed },
|
|
784
865
|
...speedFromRace(resolved) !== raceSpeed ? [{ source: "Feats", amount: speedFromRace(resolved) - raceSpeed }] : [],
|
|
@@ -788,14 +869,14 @@ function recalc(resolved, registry) {
|
|
|
788
869
|
...conditionSpeed !== baseSpeed ? [{ source: "Conditions", amount: conditionSpeed - baseSpeed }] : []
|
|
789
870
|
];
|
|
790
871
|
if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
|
|
791
|
-
const init = (
|
|
872
|
+
const init = (_J = overrides.initiative) != null ? _J : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
|
|
792
873
|
const initiativeBreakdown = [
|
|
793
874
|
{ source: "DEX", amount: mods.dex },
|
|
794
875
|
...initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) !== mods.dex ? [{ source: "Feats", amount: initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) - mods.dex }] : [],
|
|
795
876
|
...featureEffects.initiative_terms.map((term) => ({ source: term.label, amount: term.value }))
|
|
796
877
|
];
|
|
797
878
|
const senses = {
|
|
798
|
-
darkvision: Math.max((
|
|
879
|
+
darkvision: Math.max((_M = (_L = (_K = resolved.race) == null ? void 0 : _K.vision) == null ? void 0 : _L.darkvision) != null ? _M : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
|
|
799
880
|
blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
|
|
800
881
|
tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
|
|
801
882
|
truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
|
|
@@ -842,28 +923,42 @@ function recalc(resolved, registry) {
|
|
|
842
923
|
const spellLimits = computeSpellLimits(limitInputs);
|
|
843
924
|
const defenses = {
|
|
844
925
|
resistances: suppress(resolved, "resistances", composeDefenseEntries(
|
|
845
|
-
(
|
|
926
|
+
(_O = (_N = resolved.definition.defenses) == null ? void 0 : _N.resistances) != null ? _O : [],
|
|
846
927
|
applied.defenses.resistances,
|
|
847
928
|
featureEffects.resistances
|
|
848
929
|
)),
|
|
849
930
|
immunities: suppress(resolved, "immunities", composeDefenseEntries(
|
|
850
|
-
(
|
|
931
|
+
(_Q = (_P = resolved.definition.defenses) == null ? void 0 : _P.immunities) != null ? _Q : [],
|
|
851
932
|
applied.defenses.immunities,
|
|
852
933
|
featureEffects.immunities
|
|
853
934
|
)),
|
|
854
935
|
vulnerabilities: suppress(resolved, "vulnerabilities", composeDefenseEntries(
|
|
855
|
-
(
|
|
936
|
+
(_S = (_R = resolved.definition.defenses) == null ? void 0 : _R.vulnerabilities) != null ? _S : [],
|
|
856
937
|
applied.defenses.vulnerabilities,
|
|
857
938
|
featureEffects.vulnerabilities
|
|
858
939
|
)),
|
|
859
940
|
condition_immunities: suppress(resolved, "condition_immunities", composeDefenseEntries(
|
|
860
|
-
(
|
|
941
|
+
(_U = (_T = resolved.definition.defenses) == null ? void 0 : _T.condition_immunities) != null ? _U : [],
|
|
861
942
|
applied.defenses.condition_immunities,
|
|
862
943
|
featureEffects.condition_immunities
|
|
863
944
|
))
|
|
864
945
|
};
|
|
865
|
-
const attackRows = [...(
|
|
946
|
+
const attackRows = [...(_V = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _V : [], buildUnarmedRow(mods, proficiencyBonus, resolveUnarmedStrike(resolved))];
|
|
866
947
|
const riderBindings = (owner) => amountBindingsFor(owner, resolved, { proficiencyBonus, mods, spellcastingClasses });
|
|
948
|
+
const ownSpells = (_W = resolved.spells) != null ? _W : [];
|
|
949
|
+
const spellDamageRiders = featureEffects.spellDamageBonuses.flatMap((r) => {
|
|
950
|
+
const reached = /* @__PURE__ */ new Set([...spellsReached(r.targets, ownSpells), ...spellsInScope(r.scope, ownSpells, (id) => pickedDamageTypes(resolved, id))]);
|
|
951
|
+
const spells = [...new Set(ownSpells.map((s) => s.slug))].filter((slug) => reached.has(slug));
|
|
952
|
+
if (!spells.length) return [];
|
|
953
|
+
const { owner, targets: _targets, scope, damage_type, ...rest } = r;
|
|
954
|
+
return [{
|
|
955
|
+
...rest,
|
|
956
|
+
amount: resolveAmountText(r.amount, riderBindings(owner)),
|
|
957
|
+
...damage_type && isCanonicalDamageType(damage_type) ? { damage_type } : {},
|
|
958
|
+
...(scope == null ? void 0 : scope.once) ? { once: true } : {},
|
|
959
|
+
spells
|
|
960
|
+
}];
|
|
961
|
+
});
|
|
867
962
|
return {
|
|
868
963
|
totalLevel,
|
|
869
964
|
proficiencyBonus,
|
|
@@ -915,10 +1010,11 @@ function recalc(resolved, registry) {
|
|
|
915
1010
|
...riders.length ? { damageRiders: riders } : {}
|
|
916
1011
|
};
|
|
917
1012
|
}),
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1013
|
+
...spellDamageRiders.length ? { spellDamageRiders } : {},
|
|
1014
|
+
equippedSlots: (_X = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _X : {},
|
|
1015
|
+
carriedWeight: (_Y = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _Y : 0,
|
|
1016
|
+
attunementUsed: (_Z = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _Z : 0,
|
|
1017
|
+
attunementLimit: (_$ = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _$ : (__ = overrides.attunement_limit) != null ? __ : Math.max(3, featureEffects.attunement_set),
|
|
922
1018
|
conditionEffects,
|
|
923
1019
|
rollModifiers: featureEffects.rollModifiers,
|
|
924
1020
|
saveOutcomes: featureEffects.saveOutcomes
|
package/dist/pc/pc.resolver.d.ts
CHANGED
|
@@ -114,7 +114,10 @@ export declare function collectItemGrantedSpells(character: Character, ownAbilit
|
|
|
114
114
|
* never lost. Item-source spells carry INSTANCE identity: they key by
|
|
115
115
|
* `slug + "#" + entryIndex`, so two scrolls of one spell stay two rows and a scroll of
|
|
116
116
|
* a class-known spell keeps its OWN item row, never collapsing into / being collapsed
|
|
117
|
-
* by a class/feat copy. The class/feat slug-only merge is unchanged.
|
|
117
|
+
* by a class/feat copy. The class/feat slug-only merge is unchanged. An AT-WILL copy (a pool member's innate grant) keys
|
|
118
|
+
* by `slug + "#atwill"` (review D1, coordinator ruling 2026-09-28): it is a row of its own beside a copy the character
|
|
119
|
+
* already has (the slotted cast can upcast and target others), neither row's flags cross to the other, and two at-will
|
|
120
|
+
* copies of one spell are still one row.
|
|
118
121
|
*/
|
|
119
122
|
export declare function dedupeResolvedSpells(spells: ResolvedSpell[]): ResolvedSpell[];
|
|
120
123
|
/** Selected select-entity values (optional-features) and selected inline
|
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -10,30 +10,31 @@ import {
|
|
|
10
10
|
dedupeResolvedSpells,
|
|
11
11
|
resolveOriginFeat,
|
|
12
12
|
stripSlug
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-EJD47JHL.js";
|
|
14
14
|
import "../chunk-2LULMQTF.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-QA3YCOML.js";
|
|
16
|
+
import "../chunk-64VNLMSG.js";
|
|
17
17
|
import "../chunk-TOM66P2P.js";
|
|
18
18
|
import "../chunk-KU3YLF6D.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-5JXFJ5AU.js";
|
|
20
|
+
import "../chunk-RD2MID3M.js";
|
|
21
|
+
import "../chunk-LICYHPI3.js";
|
|
22
|
+
import "../chunk-PVCEA4HZ.js";
|
|
20
23
|
import "../chunk-KSTV7J2U.js";
|
|
21
24
|
import "../chunk-DPUJDOKV.js";
|
|
22
25
|
import "../chunk-LBEXLN6I.js";
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-3VZZDKRA.js";
|
|
26
|
+
import "../chunk-NXUY5XQN.js";
|
|
25
27
|
import "../chunk-W6GC6OKK.js";
|
|
26
28
|
import "../chunk-B3DP42OM.js";
|
|
27
29
|
import "../chunk-IUAAXXNO.js";
|
|
28
30
|
import "../chunk-YHYTW5QA.js";
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-PVCEA4HZ.js";
|
|
31
|
+
import "../chunk-ZUQW5VBZ.js";
|
|
31
32
|
import "../chunk-IHE6KVC3.js";
|
|
32
33
|
import "../chunk-LHZXYFBU.js";
|
|
33
34
|
import "../chunk-YBLDE5CG.js";
|
|
34
|
-
import "../chunk-ZUQW5VBZ.js";
|
|
35
35
|
import "../chunk-LVQLWRCU.js";
|
|
36
36
|
import "../chunk-CM5CWO4K.js";
|
|
37
|
+
import "../chunk-4J6DS3EJ.js";
|
|
37
38
|
import "../chunk-EVMUJYUD.js";
|
|
38
39
|
import "../chunk-VTTA2ALZ.js";
|
|
39
40
|
import "../chunk-ZCTUYGNV.js";
|