@archivist-gg/dnd5e 0.3.10 → 0.3.13
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/LICENSES/SRD.md +38 -3
- package/dist/armor/armor.codec.js +3 -3
- package/dist/armor/armor.parser.js +2 -2
- package/dist/armor/armor.schema.d.ts +1 -0
- package/dist/armor/armor.schema.js +1 -1
- package/dist/armor/armor.types.d.ts +2 -0
- 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-2LULMQTF.js +14 -0
- package/dist/{chunk-CBEKVAX4.js → chunk-4BZ47YJ4.js} +10 -3
- package/dist/{chunk-22MOUU2G.js → chunk-4SLOJXJ4.js} +1 -1
- package/dist/{chunk-2DFENQIJ.js → chunk-5GKJAUMX.js} +2 -0
- package/dist/{chunk-J77CKYV3.js → chunk-5KGV6TF7.js} +1 -1
- package/dist/{chunk-3UNP3G4D.js → chunk-6ZY3U6BQ.js} +1 -1
- package/dist/{chunk-DNAJRMNN.js → chunk-A54HHCWW.js} +6 -7
- package/dist/{chunk-2M34FLAY.js → chunk-BRGLDWUP.js} +3 -1
- package/dist/chunk-CM5CWO4K.js +735 -0
- package/dist/{chunk-MI7P3NX3.js → chunk-DPM6V7YX.js} +2 -2
- package/dist/chunk-EJP263OP.js +186 -0
- package/dist/{chunk-G247QXWW.js → chunk-EL6QPF6I.js} +1 -1
- package/dist/{chunk-SMLXZUBH.js → chunk-EYX4JMAU.js} +4 -1
- package/dist/{chunk-AW3EHF3L.js → chunk-FC4IGH5Y.js} +1 -1
- package/dist/{chunk-PI4LLJG4.js → chunk-FPGXFD2M.js} +2 -2
- package/dist/{chunk-23LZLBJK.js → chunk-G6MHJDVT.js} +6 -2
- package/dist/{chunk-NWDF5HG3.js → chunk-G7ED5H2G.js} +1 -1
- package/dist/chunk-H5PTKYXL.js +101 -0
- package/dist/{chunk-LWFTHJIE.js → chunk-HHBD4SQ6.js} +1 -1
- package/dist/{chunk-PP2UHLBA.js → chunk-HJQNK3J5.js} +8 -0
- package/dist/{chunk-JC5UNIVM.js → chunk-HS6FIOLP.js} +2 -0
- package/dist/chunk-IHE6KVC3.js +13 -0
- package/dist/{chunk-BLRW2UU6.js → chunk-J53ERF6K.js} +2 -2
- package/dist/{chunk-MQ747UCR.js → chunk-JNNNBEUH.js} +65 -2
- package/dist/{chunk-LDDCNPHD.js → chunk-K5NJBTE2.js} +1 -1
- package/dist/{chunk-4ISR76DH.js → chunk-KSTV7J2U.js} +9 -3
- package/dist/chunk-LBEXLN6I.js +91 -0
- package/dist/{chunk-UBBKSYBY.js → chunk-LHZXYFBU.js} +30 -1
- package/dist/{chunk-OYUEUKKF.js → chunk-LVX6TQ3R.js} +12 -8
- package/dist/{chunk-R747YKS7.js → chunk-M2OWVAZG.js} +1 -1
- package/dist/{chunk-7YU4NPKR.js → chunk-MC5YJ4PB.js} +1 -1
- package/dist/{chunk-JCEV7KYN.js → chunk-MUIU7RZ3.js} +1 -1
- package/dist/{chunk-JSZ4H6AQ.js → chunk-MWCCGPG3.js} +1 -1
- package/dist/{chunk-R2ZV233X.js → chunk-MYY2C5MB.js} +3 -3
- package/dist/{chunk-S56D6B6C.js → chunk-PLOSP4XQ.js} +3 -3
- package/dist/{chunk-JANNRGJC.js → chunk-PX25R3DK.js} +1 -1
- package/dist/{chunk-V373TRJE.js → chunk-Q5XTEYHD.js} +191 -125
- package/dist/{chunk-MAH6DCRI.js → chunk-Q6UOHCCT.js} +1 -1
- package/dist/{chunk-HLQAFZKQ.js → chunk-QEO7LYTG.js} +216 -95
- package/dist/{chunk-PJMG5XV3.js → chunk-QSBJ6NEM.js} +1 -1
- package/dist/{chunk-BL3VELKP.js → chunk-R2V5LN3I.js} +1 -1
- package/dist/{chunk-4DOMDEBZ.js → chunk-RQNJXADQ.js} +1 -1
- package/dist/{chunk-GFZ7PITJ.js → chunk-S3YUXDSC.js} +6 -1
- package/dist/chunk-T5GZBKIQ.js +927 -0
- package/dist/{chunk-PZCE7DJM.js → chunk-UE6LKRXQ.js} +15 -1
- package/dist/{chunk-5N2GW72F.js → chunk-UZXG6QSY.js} +2 -1
- package/dist/{chunk-QHMWA3SZ.js → chunk-VDPRBUU5.js} +1 -1
- package/dist/{chunk-4XTNPNQB.js → chunk-VPYBK2MG.js} +1 -1
- package/dist/{chunk-V6LJFP4R.js → chunk-X7VZY4ON.js} +2 -2
- package/dist/{chunk-HZA7OE7N.js → chunk-XCFC7LGF.js} +2 -1
- package/dist/{chunk-BIA32MQ5.js → chunk-XJRNEQPD.js} +1 -1
- package/dist/{chunk-OZP6JFGT.js → chunk-XY6X2APM.js} +3 -1
- package/dist/{chunk-UIRMA5KM.js → chunk-YDGMBMYI.js} +1 -1
- package/dist/{chunk-6X4KUDMU.js → chunk-ZCTUYGNV.js} +7 -2
- package/dist/{chunk-VQAXTIBW.js → chunk-ZDAEGJH4.js} +2 -0
- package/dist/{chunk-XTRDCSJB.js → chunk-ZMJQUZQH.js} +4 -1
- package/dist/chunk-ZUQW5VBZ.js +89 -0
- package/dist/class/class.codec.js +7 -7
- package/dist/class/class.parser.js +6 -6
- package/dist/class/class.schema.d.ts +10 -0
- package/dist/class/class.schema.js +5 -5
- package/dist/entities/base-item-resolver.js +2 -2
- package/dist/entities/slug.d.ts +18 -8
- package/dist/entities/slug.js +3 -1
- package/dist/feat/feat.codec.js +5 -5
- package/dist/feat/feat.parser.js +4 -4
- package/dist/feat/feat.schema.d.ts +16 -3
- package/dist/feat/feat.schema.js +3 -3
- package/dist/index.js +5277 -2017
- package/dist/item/item.actions-map.d.ts +40 -5
- package/dist/item/item.actions-map.js +5 -84
- package/dist/item/item.attunement.js +3 -9
- package/dist/item/item.bonuses.js +5 -2
- package/dist/item/item.codec.js +3 -3
- package/dist/item/item.conditions.js +4 -1
- package/dist/item/item.conditions.types.d.ts +4 -0
- package/dist/item/item.cost.d.ts +3 -0
- package/dist/item/item.cost.js +29 -0
- package/dist/item/item.icon.d.ts +15 -0
- package/dist/item/item.icon.js +211 -0
- package/dist/item/item.parser.js +2 -2
- package/dist/item/item.schema.d.ts +16 -1
- package/dist/item/item.schema.js +3 -1
- package/dist/item/item.types.d.ts +9 -2
- package/dist/monster/monster.parser.js +5 -5
- package/dist/monster/monster.schema.js +4 -4
- package/dist/optional-feature/optional-feature.codec.js +4 -4
- package/dist/optional-feature/optional-feature.parser.js +3 -3
- package/dist/optional-feature/optional-feature.schema.d.ts +229 -3
- package/dist/optional-feature/optional-feature.schema.js +6 -2
- package/dist/pc/pc.additional-spells.js +4 -4
- package/dist/pc/pc.asi-flatten.d.ts +62 -1
- package/dist/pc/pc.asi-flatten.js +16 -0
- package/dist/pc/pc.conditions.js +1 -1
- package/dist/pc/pc.containment.d.ts +45 -0
- package/dist/pc/pc.containment.js +24 -0
- package/dist/pc/pc.decision-engine.d.ts +21 -3
- package/dist/pc/pc.decision-engine.js +23 -14
- package/dist/pc/pc.entry-overrides.d.ts +79 -0
- package/dist/pc/pc.entry-overrides.js +40 -0
- package/dist/pc/pc.equipment.d.ts +2 -2
- package/dist/pc/pc.equipment.js +18 -7
- package/dist/pc/pc.feature-effects.js +2 -2
- package/dist/pc/pc.infusions.d.ts +220 -0
- package/dist/pc/pc.infusions.js +64 -0
- package/dist/pc/pc.parser.js +18 -1
- package/dist/pc/pc.pools.d.ts +1 -1
- package/dist/pc/pc.pools.js +11 -3
- package/dist/pc/pc.proficiencies.js +21 -14
- package/dist/pc/pc.recalc.d.ts +39 -36
- package/dist/pc/pc.recalc.js +60 -32
- package/dist/pc/pc.resolver.js +21 -14
- package/dist/pc/pc.resource-seed.js +1 -1
- package/dist/pc/pc.resources.d.ts +6 -1
- package/dist/pc/pc.resources.js +3 -1
- package/dist/pc/pc.rest.d.ts +21 -1
- package/dist/pc/pc.rest.js +52 -19
- package/dist/pc/pc.schema.d.ts +14 -0
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.slotting.d.ts +36 -3
- package/dist/pc/pc.slotting.js +13 -5
- package/dist/pc/pc.tool-picks.d.ts +51 -0
- package/dist/pc/pc.tool-picks.js +18 -0
- package/dist/pc/pc.types.d.ts +70 -12
- package/dist/pc/pool-layout.d.ts +14 -0
- package/dist/pc/pool-layout.js +7 -3
- 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/attack-schema.d.ts +1 -1
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/feature-effect-schema.d.ts +16 -3
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.js +3 -3
- package/dist/schemas/selection-pool-schema.d.ts +10 -0
- package/dist/schemas/selection-pool-schema.js +1 -1
- package/dist/spell/spell.codec.js +3 -3
- package/dist/spell/spell.parser.js +2 -2
- package/dist/spell/spell.scaling.d.ts +34 -10
- package/dist/spell/spell.scaling.js +36 -4
- package/dist/spell/spell.schema.d.ts +1 -0
- package/dist/spell/spell.schema.js +1 -1
- package/dist/spell/spell.types.d.ts +4 -0
- package/dist/srd/retired-items.d.ts +14 -0
- package/dist/srd/retired-items.js +11 -0
- package/dist/subclass/subclass.codec.js +7 -7
- package/dist/subclass/subclass.parser.js +6 -6
- package/dist/subclass/subclass.schema.d.ts +10 -0
- package/dist/subclass/subclass.schema.js +5 -5
- package/dist/types/choice.d.ts +8 -0
- package/dist/types/equipment-grant.d.ts +18 -1
- package/dist/types/equipment-grant.js +12 -0
- package/dist/types/feature-effect.d.ts +6 -1
- package/dist/types/optional-feature.types.d.ts +79 -1
- package/dist/types/selection-pool.d.ts +16 -1
- package/dist/weapon/weapon.classify.d.ts +10 -8
- package/dist/weapon/weapon.classify.js +2 -2
- package/dist/weapon/weapon.codec.js +3 -3
- package/dist/weapon/weapon.parser.js +2 -2
- package/dist/weapon/weapon.schema.d.ts +1 -0
- package/dist/weapon/weapon.schema.js +1 -1
- package/dist/weapon/weapon.types.d.ts +2 -0
- package/package.json +1 -1
- package/dist/chunk-O4SRD3J5.js +0 -165
- package/dist/chunk-WXWPK3LI.js +0 -55
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
equipmentCategoryKey,
|
|
3
|
+
isCategoryGrant
|
|
4
|
+
} from "./chunk-2LULMQTF.js";
|
|
5
|
+
import {
|
|
6
|
+
TOOL_CATEGORIES,
|
|
7
|
+
backgroundToolPicks,
|
|
8
|
+
categoryWords,
|
|
9
|
+
classToolPicks,
|
|
10
|
+
expandToolPool,
|
|
11
|
+
toolCategoriesOf
|
|
12
|
+
} from "./chunk-H5PTKYXL.js";
|
|
1
13
|
import {
|
|
2
14
|
resolveFeatureResources,
|
|
3
15
|
resolveResourceIndex
|
|
4
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-KSTV7J2U.js";
|
|
5
17
|
import {
|
|
6
18
|
attributeUnclassedSpell,
|
|
7
19
|
effectiveSpellcastingAbility,
|
|
@@ -9,9 +21,25 @@ import {
|
|
|
9
21
|
resolveSpellcasting
|
|
10
22
|
} from "./chunk-DPUJDOKV.js";
|
|
11
23
|
import {
|
|
24
|
+
assembleEffectFeatures,
|
|
25
|
+
collectProficiencyEffectGrants
|
|
26
|
+
} from "./chunk-4BZ47YJ4.js";
|
|
27
|
+
import {
|
|
28
|
+
ALL_LANGUAGES,
|
|
29
|
+
ALL_SKILL_SLUGS,
|
|
30
|
+
ALL_TOOLS
|
|
31
|
+
} from "./chunk-KU3YLF6D.js";
|
|
32
|
+
import {
|
|
33
|
+
humanizeProficiency,
|
|
34
|
+
proficiencyLabel,
|
|
35
|
+
toProfSlug
|
|
36
|
+
} from "./chunk-RLGQ5PZZ.js";
|
|
37
|
+
import {
|
|
38
|
+
buildInfusionContext,
|
|
12
39
|
resolveAllPools,
|
|
40
|
+
resolveOptionRows,
|
|
13
41
|
strandedPicks
|
|
14
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-T5GZBKIQ.js";
|
|
15
43
|
import {
|
|
16
44
|
countColumnsFor,
|
|
17
45
|
readTableColumn
|
|
@@ -21,32 +49,23 @@ import {
|
|
|
21
49
|
} from "./chunk-YHYTW5QA.js";
|
|
22
50
|
import {
|
|
23
51
|
collectAdditionalSpells
|
|
24
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-DPM6V7YX.js";
|
|
53
|
+
import {
|
|
54
|
+
convertibleLegacyAsi,
|
|
55
|
+
flattenAsiOrFeat,
|
|
56
|
+
resolveLegacyAsiFeat
|
|
57
|
+
} from "./chunk-LBEXLN6I.js";
|
|
25
58
|
import {
|
|
26
59
|
isItemEntity,
|
|
27
60
|
resolveEntityForEntry
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import {
|
|
30
|
-
assembleEffectFeatures,
|
|
31
|
-
collectProficiencyEffectGrants
|
|
32
|
-
} from "./chunk-CBEKVAX4.js";
|
|
33
|
-
import {
|
|
34
|
-
ALL_LANGUAGES,
|
|
35
|
-
ALL_SKILL_SLUGS,
|
|
36
|
-
ALL_TOOLS
|
|
37
|
-
} from "./chunk-KU3YLF6D.js";
|
|
38
|
-
import {
|
|
39
|
-
humanizeProficiency,
|
|
40
|
-
proficiencyLabel,
|
|
41
|
-
toProfSlug
|
|
42
|
-
} from "./chunk-RLGQ5PZZ.js";
|
|
61
|
+
} from "./chunk-LHZXYFBU.js";
|
|
43
62
|
import {
|
|
44
63
|
warnOnce
|
|
45
64
|
} from "./chunk-LVQLWRCU.js";
|
|
46
65
|
import {
|
|
47
66
|
bareEntitySlug,
|
|
48
67
|
wikilinkTailSlug
|
|
49
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-ZCTUYGNV.js";
|
|
50
69
|
import {
|
|
51
70
|
FEATURE_TYPE_FOR_CATEGORY,
|
|
52
71
|
featProgressionCategory
|
|
@@ -56,7 +75,7 @@ import {
|
|
|
56
75
|
} from "./chunk-EVMUJYUD.js";
|
|
57
76
|
import {
|
|
58
77
|
mirrorSpellShapes
|
|
59
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-XY6X2APM.js";
|
|
60
79
|
import {
|
|
61
80
|
ABILITY_KEYS
|
|
62
81
|
} from "./chunk-WELIKLZF.js";
|
|
@@ -80,6 +99,7 @@ function collectProficiencyGrants(resolved) {
|
|
|
80
99
|
for (const w of (_f = (_e = prof.weapons) == null ? void 0 : _e.fixed) != null ? _f : []) classWeaponFixed.push({ value: w, source });
|
|
81
100
|
for (const w of (_h = (_g = prof.weapons) == null ? void 0 : _g.categories) != null ? _h : []) classWeaponCategories.push({ value: w, source });
|
|
82
101
|
for (const t of (_j = (_i = prof.tools) == null ? void 0 : _i.fixed) != null ? _j : []) classToolFixed.push({ value: t, source });
|
|
102
|
+
for (const t of classToolPicks(c.entity).grants) classToolFixed.push({ value: t, source });
|
|
83
103
|
}
|
|
84
104
|
const raceSource = (_l = (_k = resolved.race) == null ? void 0 : _k.name) != null ? _l : UNKNOWN_SOURCE;
|
|
85
105
|
const raceLangFixed = ((_o = (_n = (_m = resolved.race) == null ? void 0 : _m.languages) == null ? void 0 : _n.fixed) != null ? _o : []).map(
|
|
@@ -95,6 +115,7 @@ function collectProficiencyGrants(resolved) {
|
|
|
95
115
|
for (const t of entry.items) bgToolFixed.push({ value: t, source });
|
|
96
116
|
}
|
|
97
117
|
}
|
|
118
|
+
for (const t of backgroundToolPicks(bg).grants) bgToolFixed.push({ value: t, source });
|
|
98
119
|
for (const entry of (_r = bg.language_proficiencies) != null ? _r : []) {
|
|
99
120
|
if (entry.kind === "fixed") {
|
|
100
121
|
for (const l of entry.languages) bgLangFixed.push({ value: l, source });
|
|
@@ -164,25 +185,18 @@ function collectProficiencyGrants(resolved) {
|
|
|
164
185
|
};
|
|
165
186
|
}
|
|
166
187
|
|
|
167
|
-
// src/pc/pc.asi-flatten.ts
|
|
168
|
-
function flattenAsiOrFeat(choice) {
|
|
169
|
-
var _a;
|
|
170
|
-
if (choice.kind !== "select-inline" || choice.id !== "asi-or-feat") return choice;
|
|
171
|
-
const featBranches = choice.options.filter((o) => {
|
|
172
|
-
var _a2;
|
|
173
|
-
return ((_a2 = o.choices) != null ? _a2 : []).some((c) => c.kind === "select-entity" && c.entity_type === "feat");
|
|
174
|
-
});
|
|
175
|
-
if (featBranches.length !== 1) return choice;
|
|
176
|
-
const inner = (_a = featBranches[0].choices) != null ? _a : [];
|
|
177
|
-
if (inner.length !== 1) return choice;
|
|
178
|
-
const only = inner[0];
|
|
179
|
-
if (only.kind !== "select-entity" || only.entity_type !== "feat") return choice;
|
|
180
|
-
return only;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
188
|
// src/pc/pc.decision-engine.ts
|
|
184
189
|
var warnedDegradedEquipment = /* @__PURE__ */ new Set();
|
|
185
190
|
var warnedAmbiguousBare = /* @__PURE__ */ new Set();
|
|
191
|
+
var foldedTypeMemo = /* @__PURE__ */ new Map();
|
|
192
|
+
function foldedType(s) {
|
|
193
|
+
let v = foldedTypeMemo.get(s);
|
|
194
|
+
if (v === void 0) {
|
|
195
|
+
v = categoryWords(s).join(" ");
|
|
196
|
+
foldedTypeMemo.set(s, v);
|
|
197
|
+
}
|
|
198
|
+
return v;
|
|
199
|
+
}
|
|
186
200
|
function matchesFilter(e, where, ownerBare) {
|
|
187
201
|
var _a, _b, _c, _d, _e;
|
|
188
202
|
const d = e.data;
|
|
@@ -198,6 +212,14 @@ function matchesFilter(e, where, ownerBare) {
|
|
|
198
212
|
if (where.armor_category) {
|
|
199
213
|
if (((_d = d.category) != null ? _d : "").toLowerCase() !== where.armor_category) return false;
|
|
200
214
|
}
|
|
215
|
+
if (where.item_type) {
|
|
216
|
+
const t = foldedType(typeof d.type === "string" ? d.type : "");
|
|
217
|
+
if (!t || !where.item_type.some((x) => foldedType(x) === t)) return false;
|
|
218
|
+
}
|
|
219
|
+
if (where.mundane) {
|
|
220
|
+
const r = typeof d.rarity === "string" ? d.rarity.trim().toLowerCase() : "";
|
|
221
|
+
if (r && r !== "none" && r !== "mundane") return false;
|
|
222
|
+
}
|
|
201
223
|
if (where.parent_class === "self") {
|
|
202
224
|
if (!d.parent_class || wikilinkTailSlug(d.parent_class) !== ownerBare) return false;
|
|
203
225
|
}
|
|
@@ -208,17 +230,94 @@ function matchesFilter(e, where, ownerBare) {
|
|
|
208
230
|
return true;
|
|
209
231
|
}
|
|
210
232
|
var __matchesFilterForTest = matchesFilter;
|
|
233
|
+
function parseEquipmentCategory(category) {
|
|
234
|
+
const tools = toolCategoriesOf(category);
|
|
235
|
+
if (tools) return { kind: "tool", tools };
|
|
236
|
+
const words = categoryWords(category).filter((w) => w !== "any");
|
|
237
|
+
const has = (w) => words.includes(w);
|
|
238
|
+
const only = (allowed) => words.every((w) => allowed.includes(w));
|
|
239
|
+
if (words.length === 1 && has("shield")) return { kind: "shield" };
|
|
240
|
+
if (has("armor") && only(["armor", "light", "medium", "heavy"]) && words.length <= 2) {
|
|
241
|
+
const armor = ["light", "medium", "heavy"].find((k) => has(k));
|
|
242
|
+
return { kind: "armor", armor };
|
|
243
|
+
}
|
|
244
|
+
if (has("weapon") && only(["weapon", "simple", "martial", "melee", "ranged"])) {
|
|
245
|
+
const klass = ["simple", "martial"].filter((k) => has(k));
|
|
246
|
+
const range = ["melee", "ranged"].filter((k) => has(k));
|
|
247
|
+
if (klass.length === 1 && range.length <= 1 && words.length === 2 + range.length) {
|
|
248
|
+
return { kind: "weapon", weapon: klass[0], range: range[0] };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
211
253
|
function categoryToEntitySelect(category, id) {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
254
|
+
const spec = parseEquipmentCategory(category);
|
|
255
|
+
const pick = { kind: "select-entity", id, count: 1 };
|
|
256
|
+
switch (spec == null ? void 0 : spec.kind) {
|
|
257
|
+
case "shield":
|
|
258
|
+
return { ...pick, label: "Choose a shield", entity_type: "armor", where: { armor_category: "shield" } };
|
|
259
|
+
case "armor":
|
|
260
|
+
return spec.armor ? { ...pick, label: `Choose ${spec.armor} armor`, entity_type: "armor", where: { armor_category: spec.armor } } : { ...pick, label: "Choose armor", entity_type: "armor" };
|
|
261
|
+
case "weapon":
|
|
262
|
+
return {
|
|
263
|
+
...pick,
|
|
264
|
+
label: `Choose a ${spec.weapon}${spec.range ? ` ${spec.range}` : ""} weapon`,
|
|
265
|
+
entity_type: "weapon",
|
|
266
|
+
where: { weapon_category: spec.weapon }
|
|
267
|
+
};
|
|
268
|
+
case "tool":
|
|
269
|
+
return {
|
|
270
|
+
...pick,
|
|
271
|
+
label: `Choose ${spec.tools.map((t) => TOOL_CATEGORIES[t].label).join(" or ")}`,
|
|
272
|
+
entity_type: "item",
|
|
273
|
+
where: { item_type: spec.tools.map((t) => TOOL_CATEGORIES[t].itemType), mundane: true }
|
|
274
|
+
};
|
|
275
|
+
default:
|
|
276
|
+
warnOnce(
|
|
277
|
+
`equipment-category:${category}`,
|
|
278
|
+
`Archivist: starting-equipment category "${category}" is not a known item category; its pick offers no options.`
|
|
279
|
+
);
|
|
280
|
+
return { ...pick, label: `Choose a ${category.replace(/[-_]+/g, " ")}`, entity_type: "item", from: [] };
|
|
215
281
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
282
|
+
}
|
|
283
|
+
var __categoryToEntitySelectForTest = categoryToEntitySelect;
|
|
284
|
+
function equipmentDecisions(entries, ownerSlug) {
|
|
285
|
+
const out = [];
|
|
286
|
+
let degraded = false;
|
|
287
|
+
(entries != null ? entries : []).forEach((eq, i) => {
|
|
288
|
+
var _a;
|
|
289
|
+
if ((eq == null ? void 0 : eq.kind) !== "choice") return;
|
|
290
|
+
const options = (_a = eq.options) != null ? _a : [];
|
|
291
|
+
out.push({
|
|
292
|
+
kind: "select-inline",
|
|
293
|
+
id: `equipment-${i}`,
|
|
294
|
+
label: "Starting Equipment",
|
|
295
|
+
count: 1,
|
|
296
|
+
options: options.map((opt, j) => {
|
|
297
|
+
var _a2;
|
|
298
|
+
const label = typeof opt === "string" ? opt : (_a2 = opt == null ? void 0 : opt.label) != null ? _a2 : "";
|
|
299
|
+
const wellFormed = !!opt && typeof opt === "object" && Array.isArray(opt.grants);
|
|
300
|
+
if (!wellFormed) degraded = true;
|
|
301
|
+
const grants = wellFormed ? opt.grants : [];
|
|
302
|
+
return {
|
|
303
|
+
value: `option-${j}`,
|
|
304
|
+
label,
|
|
305
|
+
choices: grants.flatMap((g, k) => isCategoryGrant(g) ? [categoryToEntitySelect(g.category, equipmentCategoryKey(i, j, k))] : [])
|
|
306
|
+
};
|
|
307
|
+
})
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
if (degraded && !warnedDegradedEquipment.has(ownerSlug)) {
|
|
311
|
+
warnedDegradedEquipment.add(ownerSlug);
|
|
312
|
+
console.warn(
|
|
313
|
+
`[archivist] Starting equipment for "${ownerSlug}" is in an outdated/unstructured format; its nested picks and seeding are skipped. Re-sync the compendium (delete _compendium.md and reload) to fix.`
|
|
314
|
+
);
|
|
219
315
|
}
|
|
220
|
-
|
|
221
|
-
|
|
316
|
+
return out;
|
|
317
|
+
}
|
|
318
|
+
function authoredProficiencyPool(choice) {
|
|
319
|
+
if (!choice.from) return void 0;
|
|
320
|
+
return choice.domain === "tool" ? expandToolPool(choice.from) : choice.from;
|
|
222
321
|
}
|
|
223
322
|
function enumerateOptions(choice, ctx, ownerBare) {
|
|
224
323
|
var _a, _b;
|
|
@@ -260,7 +359,7 @@ function enumerateOptions(choice, ctx, ownerBare) {
|
|
|
260
359
|
return filtered.map((e) => ({ value: e.slug, label: e.name, entity: e }));
|
|
261
360
|
}
|
|
262
361
|
case "select-proficiency": {
|
|
263
|
-
const pool = (_a = choice
|
|
362
|
+
const pool = (_a = authoredProficiencyPool(choice)) != null ? _a : choice.domain === "skill" ? [...ALL_SKILL_SLUGS] : choice.domain === "language" ? [...ALL_LANGUAGES] : choice.domain === "tool" ? [...ALL_TOOLS] : [];
|
|
264
363
|
return pool.map((v) => ({ value: v, label: humanizeProficiency(v) }));
|
|
265
364
|
}
|
|
266
365
|
case "ability-points": {
|
|
@@ -284,6 +383,12 @@ function requiredCount(choice) {
|
|
|
284
383
|
if (choice.kind === "select-proficiency") return choice.count;
|
|
285
384
|
return (_a = choice.count) != null ? _a : 1;
|
|
286
385
|
}
|
|
386
|
+
function capAtCount(choice, value) {
|
|
387
|
+
const folds = choice.kind === "select-proficiency" || choice.kind === "select-entity" && choice.entity_type === "weapon" && choice.id !== "weapon-mastery";
|
|
388
|
+
if (!folds || !Array.isArray(value)) return value;
|
|
389
|
+
const n = requiredCount(choice);
|
|
390
|
+
return value.length > n ? value.slice(0, n) : value;
|
|
391
|
+
}
|
|
287
392
|
function statusOf(choice, selected, satisfied) {
|
|
288
393
|
const n = selectionCount(choice, selected);
|
|
289
394
|
const need = requiredCount(choice);
|
|
@@ -317,7 +422,7 @@ function buildItem(inputChoice, source, level, featureName, readValue, ctx, owne
|
|
|
317
422
|
const keyPrefix = (_a = opts == null ? void 0 : opts.keyPrefix) != null ? _a : "";
|
|
318
423
|
const expandFeatChildren = (_b = opts == null ? void 0 : opts.expandFeatChildren) != null ? _b : true;
|
|
319
424
|
const key = keyPrefix + choice.id;
|
|
320
|
-
const raw = readValue(key);
|
|
425
|
+
const raw = capAtCount(choice, readValue(key));
|
|
321
426
|
const preExclusionOptions = enumerateOptions(choice, ctx, ownerBare);
|
|
322
427
|
let options = preExclusionOptions;
|
|
323
428
|
const mine = new Set(
|
|
@@ -440,6 +545,7 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
440
545
|
}, readAt(1)("skills"));
|
|
441
546
|
}
|
|
442
547
|
if (i === 0) walk(entity.choices, readAt(1));
|
|
548
|
+
if (i === 0) walk(classToolPicks(entity).decisions, readAt(1));
|
|
443
549
|
for (const rf of resolved.features) {
|
|
444
550
|
if (rf.source.kind !== "class" && rf.source.kind !== "subclass") continue;
|
|
445
551
|
const belongs = rf.source.kind === "class" ? rf.source.slug === entity.slug : c.subclass != null && rf.source.slug === c.subclass.slug;
|
|
@@ -462,6 +568,7 @@ function visitProficiencyChoices(resolved, visit) {
|
|
|
462
568
|
}
|
|
463
569
|
if (resolved.background) {
|
|
464
570
|
walk(resolved.background.choices, originRead("background"));
|
|
571
|
+
walk(backgroundToolPicks(resolved.background).decisions, originRead("background"));
|
|
465
572
|
if (resolved.background.feature) {
|
|
466
573
|
const feature = resolved.background.feature;
|
|
467
574
|
walk(feature.choices, originRead("background"));
|
|
@@ -476,7 +583,8 @@ var filterToPool = (vals, pool) => pool ? vals.map((v) => matchPool(v, pool)).fi
|
|
|
476
583
|
function collectChosenProficiencies(resolved) {
|
|
477
584
|
const out = { skills: [], expertise: [], languages: [], tools: [], weapons: [], saves: [] };
|
|
478
585
|
const isAbility = (v) => ABILITY_KEYS.includes(v);
|
|
479
|
-
visitProficiencyChoices(resolved, (choice,
|
|
586
|
+
visitProficiencyChoices(resolved, (choice, stored) => {
|
|
587
|
+
const selected = capAtCount(choice, stored);
|
|
480
588
|
const vals = Array.isArray(selected) ? selected : typeof selected === "string" ? [selected] : [];
|
|
481
589
|
if (choice.kind === "select-entity" && choice.entity_type === "weapon") {
|
|
482
590
|
if (choice.id === "weapon-mastery") return;
|
|
@@ -487,7 +595,7 @@ function collectChosenProficiencies(resolved) {
|
|
|
487
595
|
return;
|
|
488
596
|
}
|
|
489
597
|
if (choice.kind !== "select-proficiency") return;
|
|
490
|
-
const valid = filterToPool(vals, choice
|
|
598
|
+
const valid = filterToPool(vals, authoredProficiencyPool(choice));
|
|
491
599
|
if (choice.domain === "save") {
|
|
492
600
|
for (const v of valid) if (isAbility(v) && !out.saves.includes(v)) out.saves.push(v);
|
|
493
601
|
return;
|
|
@@ -589,7 +697,7 @@ function collectChosenAbilityPoints(resolved) {
|
|
|
589
697
|
return out;
|
|
590
698
|
}
|
|
591
699
|
function buildDecisionLedger(resolved, ctx) {
|
|
592
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
700
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
593
701
|
const eff = computeEffectiveProficiencies(resolved);
|
|
594
702
|
const chosen = collectChosenProficiencies(resolved);
|
|
595
703
|
const { features, activeBuffs } = assembleEffectFeatures(resolved);
|
|
@@ -614,7 +722,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
614
722
|
};
|
|
615
723
|
const classes = [];
|
|
616
724
|
resolved.classes.forEach((c, classIndex) => {
|
|
617
|
-
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2,
|
|
725
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o;
|
|
618
726
|
if (!c.entity) return;
|
|
619
727
|
const entity = c.entity;
|
|
620
728
|
const ownerBare = bareEntitySlug(entity.slug);
|
|
@@ -629,6 +737,19 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
629
737
|
var _a3;
|
|
630
738
|
return (_a3 = c.choices[lvl]) == null ? void 0 : _a3[id];
|
|
631
739
|
};
|
|
740
|
+
let legacyAsiFeat;
|
|
741
|
+
const legacyAsiReader = (choice, lvl) => {
|
|
742
|
+
const alloc = convertibleLegacyAsi(c.choices[lvl]);
|
|
743
|
+
if (!alloc) return null;
|
|
744
|
+
const flat = flattenAsiOrFeat(choice);
|
|
745
|
+
if (flat.kind !== "select-entity" || flat.entity_type !== "feat" || flat.from || flat.where) return null;
|
|
746
|
+
if (legacyAsiFeat === void 0) legacyAsiFeat = resolveLegacyAsiFeat(ctx.registry, entity);
|
|
747
|
+
const asi = legacyAsiFeat;
|
|
748
|
+
if (!asi) return null;
|
|
749
|
+
const raw = readAt(lvl);
|
|
750
|
+
const childKey = `feat:${asi.childId}`;
|
|
751
|
+
return (id) => id === "feat" ? asi.slug : id === childKey ? alloc : raw(id);
|
|
752
|
+
};
|
|
632
753
|
const featProgressions = [...(_a2 = entity.feat_progression) != null ? _a2 : [], ...(_c2 = (_b2 = c.subclass) == null ? void 0 : _b2.feat_progression) != null ? _c2 : []];
|
|
633
754
|
const suppressedFeatureTypes = /* @__PURE__ */ new Set();
|
|
634
755
|
for (const decl of [...(_d2 = entity.selection_pools) != null ? _d2 : [], ...(_f2 = (_e2 = c.subclass) == null ? void 0 : _e2.selection_pools) != null ? _f2 : []]) {
|
|
@@ -661,7 +782,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
661
782
|
));
|
|
662
783
|
}
|
|
663
784
|
if (classIndex === 0) {
|
|
664
|
-
for (const ch of (_i2 = entity.choices) != null ? _i2 : []) {
|
|
785
|
+
for (const ch of [...(_i2 = entity.choices) != null ? _i2 : [], ...classToolPicks(entity).decisions]) {
|
|
665
786
|
push(1, buildItem(
|
|
666
787
|
ch,
|
|
667
788
|
{ kind: "class", slug: entity.slug, level: 1 },
|
|
@@ -675,36 +796,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
675
796
|
}
|
|
676
797
|
}
|
|
677
798
|
if (classIndex === 0) {
|
|
678
|
-
(
|
|
679
|
-
var _a3;
|
|
680
|
-
if (eq.kind !== "choice") return;
|
|
681
|
-
const options = (_a3 = eq.options) != null ? _a3 : [];
|
|
682
|
-
let degraded = false;
|
|
683
|
-
const ch = {
|
|
684
|
-
kind: "select-inline",
|
|
685
|
-
id: `equipment-${i}`,
|
|
686
|
-
label: "Starting Equipment",
|
|
687
|
-
count: 1,
|
|
688
|
-
options: options.map((opt, j) => {
|
|
689
|
-
var _a4;
|
|
690
|
-
const label = typeof opt === "string" ? opt : (_a4 = opt == null ? void 0 : opt.label) != null ? _a4 : "";
|
|
691
|
-
const grants = opt && typeof opt === "object" && Array.isArray(opt.grants) ? opt.grants : [];
|
|
692
|
-
if (typeof opt === "string" || !(opt && typeof opt === "object" && Array.isArray(opt.grants))) {
|
|
693
|
-
degraded = true;
|
|
694
|
-
}
|
|
695
|
-
return {
|
|
696
|
-
value: `option-${j}`,
|
|
697
|
-
label,
|
|
698
|
-
choices: grants.flatMap((g, k) => g && typeof g === "object" && "category" in g && g.category ? [categoryToEntitySelect(g.category, `equipment-${i}-opt-${j}-cat-${k}`)] : [])
|
|
699
|
-
};
|
|
700
|
-
})
|
|
701
|
-
};
|
|
702
|
-
if (degraded && !warnedDegradedEquipment.has(entity.slug)) {
|
|
703
|
-
warnedDegradedEquipment.add(entity.slug);
|
|
704
|
-
console.warn(
|
|
705
|
-
`[archivist] Starting equipment for "${entity.slug}" is in an outdated/unstructured format; its nested picks and seeding are skipped. Re-sync the compendium (delete _compendium.md and reload) to fix.`
|
|
706
|
-
);
|
|
707
|
-
}
|
|
799
|
+
for (const ch of equipmentDecisions(entity.starting_equipment, entity.slug)) {
|
|
708
800
|
push(1, buildItem(
|
|
709
801
|
ch,
|
|
710
802
|
{ kind: "class", slug: entity.slug, level: 1 },
|
|
@@ -715,7 +807,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
715
807
|
ownerBare,
|
|
716
808
|
effective
|
|
717
809
|
));
|
|
718
|
-
}
|
|
810
|
+
}
|
|
719
811
|
}
|
|
720
812
|
let sawAuthoredSubclass = false;
|
|
721
813
|
const staged = [];
|
|
@@ -735,7 +827,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
735
827
|
staged.push({ level: atLvl, item, rank: authoredRank(src.kind, atLvl, rf.feature), seq: staged.length });
|
|
736
828
|
};
|
|
737
829
|
const emitChoices = (list, atLvl, name, description) => {
|
|
738
|
-
var _a3;
|
|
830
|
+
var _a3, _b3;
|
|
739
831
|
for (const ch of list) {
|
|
740
832
|
if (ch.kind === "select-entity" && ch.entity_type === "subclass") {
|
|
741
833
|
sawAuthoredSubclass = true;
|
|
@@ -753,7 +845,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
753
845
|
src,
|
|
754
846
|
atLvl,
|
|
755
847
|
name,
|
|
756
|
-
readAt(atLvl),
|
|
848
|
+
(_b3 = legacyAsiReader(emitted, atLvl)) != null ? _b3 : readAt(atLvl),
|
|
757
849
|
ctx,
|
|
758
850
|
ownerBare,
|
|
759
851
|
effective,
|
|
@@ -800,22 +892,22 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
800
892
|
}
|
|
801
893
|
emitChoices(list, copy.level, copy.name, copy.description);
|
|
802
894
|
};
|
|
803
|
-
for (const copy of (
|
|
895
|
+
for (const copy of (_j2 = rf.foldedFrom) != null ? _j2 : []) emitCopy({ ...copy, prose: copy.description });
|
|
804
896
|
emitCopy({
|
|
805
897
|
level: lvl,
|
|
806
898
|
name: rf.feature.name,
|
|
807
899
|
description: rf.feature.description,
|
|
808
900
|
// The card prose: the description, else the entries joined. `||`, not `??`, so an EMPTY description
|
|
809
901
|
// falls through to the entries the way this branch's own guard always did.
|
|
810
|
-
prose: rf.feature.description || (((
|
|
902
|
+
prose: rf.feature.description || (((_k2 = rf.feature.entries) == null ? void 0 : _k2.length) ? rf.feature.entries.join("\n\n") : void 0),
|
|
811
903
|
choices: rf.feature.choices
|
|
812
904
|
});
|
|
813
905
|
}
|
|
814
906
|
staged.sort((a, b) => a.rank - b.rank || a.seq - b.seq);
|
|
815
907
|
for (const s of staged) push(s.level, s.item);
|
|
816
|
-
const subclassLevel = (
|
|
908
|
+
const subclassLevel = (_l2 = entity.subclass_level) != null ? _l2 : null;
|
|
817
909
|
if (subclassLevel != null && subclassLevel <= c.level && !sawAuthoredSubclass) {
|
|
818
|
-
const featureName = (
|
|
910
|
+
const featureName = (_m2 = entity.subclass_feature_name) != null ? _m2 : "Subclass";
|
|
819
911
|
const synthChoice = {
|
|
820
912
|
kind: "select-entity",
|
|
821
913
|
id: "subclass",
|
|
@@ -851,12 +943,23 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
851
943
|
{ kind: "class", slug: entity.slug, level: pool.anchorLevel },
|
|
852
944
|
pool.anchorLevel,
|
|
853
945
|
pool.label,
|
|
854
|
-
() => pool.selected.map((e) => e.
|
|
946
|
+
() => pool.selected.map((e) => e.key),
|
|
855
947
|
ctx,
|
|
856
948
|
ownerBare,
|
|
857
949
|
effective
|
|
858
950
|
);
|
|
859
951
|
item.pool = { id: pool.id, anchorLevel: pool.anchorLevel };
|
|
952
|
+
const repeatables = pool.available.filter((e) => e.entity.repeatable === true);
|
|
953
|
+
if (repeatables.length > 0) {
|
|
954
|
+
item.repeatable = repeatables.map((e) => {
|
|
955
|
+
var _a3, _b3;
|
|
956
|
+
return {
|
|
957
|
+
noteSlug: e.slug,
|
|
958
|
+
itemChoice: (_a3 = e.entity.item_choice) != null ? _a3 : "learn",
|
|
959
|
+
rows: resolveOptionRows(e.entity, ctx.registry, { edition: resolved.definition.edition, isEntityVisible: (_b3 = ctx.isEntityVisible) == null ? void 0 : _b3.bind(ctx) })
|
|
960
|
+
};
|
|
961
|
+
});
|
|
962
|
+
}
|
|
860
963
|
for (const o of item.options) if (strandedSlugs.has(o.value)) o.stranded = true;
|
|
861
964
|
push(pool.anchorLevel, item);
|
|
862
965
|
}
|
|
@@ -865,7 +968,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
865
968
|
if (!category) {
|
|
866
969
|
warnOnce(
|
|
867
970
|
`feat-progression-category:${entity.slug}:${entry.name}`,
|
|
868
|
-
`Archivist: feat_progression "${entry.name}" on "${entity.slug}" carries no category this engine maps (${((
|
|
971
|
+
`Archivist: feat_progression "${entry.name}" on "${entity.slug}" carries no category this engine maps (${((_n2 = entry.category) != null ? _n2 : []).join(", ")}); no decision is offered`
|
|
869
972
|
);
|
|
870
973
|
continue;
|
|
871
974
|
}
|
|
@@ -875,7 +978,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
875
978
|
const lvl = Number.parseInt(key, 10);
|
|
876
979
|
if (!Number.isInteger(lvl) || String(lvl) !== key) continue;
|
|
877
980
|
if (lvl > c.level) continue;
|
|
878
|
-
if (((
|
|
981
|
+
if (((_o = byLevel.get(lvl)) != null ? _o : []).some((i) => i.key === "feat")) {
|
|
879
982
|
warnOnce(
|
|
880
983
|
`feat-progression-collision:${entity.slug}:${lvl}`,
|
|
881
984
|
`Archivist: "${entry.name}" on "${entity.slug}" would add a second feat pick at level ${lvl}, where one already exists; skipping`
|
|
@@ -947,10 +1050,10 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
947
1050
|
if (resolved.background) {
|
|
948
1051
|
const bare = bareEntitySlug(resolved.background.slug);
|
|
949
1052
|
pushOrigin(
|
|
950
|
-
resolved.background.choices,
|
|
1053
|
+
[...(_l = resolved.background.choices) != null ? _l : [], ...backgroundToolPicks(resolved.background).decisions],
|
|
951
1054
|
"background",
|
|
952
1055
|
{ kind: "background", slug: resolved.background.slug },
|
|
953
|
-
(
|
|
1056
|
+
(_m = resolved.background.name) != null ? _m : "Background",
|
|
954
1057
|
bare,
|
|
955
1058
|
resolved.background.description
|
|
956
1059
|
);
|
|
@@ -973,7 +1076,7 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
973
1076
|
if (originFeat) {
|
|
974
1077
|
const featSource = { kind: "feat", slug: originFeat.feat.slug };
|
|
975
1078
|
const featBare = bareEntitySlug(originFeat.feat.slug);
|
|
976
|
-
for (const ch of (
|
|
1079
|
+
for (const ch of (_n = originFeat.feat.choices) != null ? _n : []) {
|
|
977
1080
|
origin.push(buildItem(
|
|
978
1081
|
ch,
|
|
979
1082
|
featSource,
|
|
@@ -988,6 +1091,18 @@ function buildDecisionLedger(resolved, ctx) {
|
|
|
988
1091
|
}
|
|
989
1092
|
}
|
|
990
1093
|
}
|
|
1094
|
+
for (const ch of equipmentDecisions(resolved.background.equipment, resolved.background.slug)) {
|
|
1095
|
+
origin.push(buildItem(
|
|
1096
|
+
ch,
|
|
1097
|
+
{ kind: "background", slug: resolved.background.slug },
|
|
1098
|
+
0,
|
|
1099
|
+
"Starting Equipment",
|
|
1100
|
+
originRead("background"),
|
|
1101
|
+
ctx,
|
|
1102
|
+
bare,
|
|
1103
|
+
effective
|
|
1104
|
+
));
|
|
1105
|
+
}
|
|
991
1106
|
}
|
|
992
1107
|
return { classes, origin };
|
|
993
1108
|
}
|
|
@@ -1014,7 +1129,10 @@ function resolveOriginFeat(entities, originFeatRef, ownerSlug) {
|
|
|
1014
1129
|
const sameCompendiumTail = (s) => prefix ? feats.find((f) => f.slug.startsWith(`${prefix}_feat_`) && f.slug.endsWith(`_${s}`)) : void 0;
|
|
1015
1130
|
const anyTail = (s) => feats.find((f) => f.slug.endsWith(`_${s}`));
|
|
1016
1131
|
const tiers = [
|
|
1017
|
-
() =>
|
|
1132
|
+
() => {
|
|
1133
|
+
var _a2;
|
|
1134
|
+
return (_a2 = feats.find((f) => f.slug === inner)) != null ? _a2 : feats.find((f) => f.slug === slug);
|
|
1135
|
+
},
|
|
1018
1136
|
// 1 exact slug
|
|
1019
1137
|
() => byPath(inner),
|
|
1020
1138
|
// 2 PATH
|
|
@@ -1186,6 +1304,8 @@ var PCResolver = class {
|
|
|
1186
1304
|
};
|
|
1187
1305
|
resolvedCharacter.pools = resolveAllPools(resolvedCharacter, this.entities, featureResources);
|
|
1188
1306
|
resolvedCharacter.resources = resolveResourceIndex(resolvedCharacter);
|
|
1307
|
+
const infusions = buildInfusionContext(character, resolvedCharacter, this.entities);
|
|
1308
|
+
if (infusions) resolvedCharacter.infusions = infusions;
|
|
1189
1309
|
return { character: resolvedCharacter, warnings };
|
|
1190
1310
|
}
|
|
1191
1311
|
};
|
|
@@ -1622,6 +1742,7 @@ export {
|
|
|
1622
1742
|
collectResolvedFeatures,
|
|
1623
1743
|
collectProficiencyGrants,
|
|
1624
1744
|
__matchesFilterForTest,
|
|
1745
|
+
__categoryToEntitySelectForTest,
|
|
1625
1746
|
collectChosenProficiencies,
|
|
1626
1747
|
computeEffectiveProficiencies,
|
|
1627
1748
|
collectChosenAbilityPoints,
|
|
@@ -174,8 +174,9 @@ var containerCapacitySchema = z.strictObject({
|
|
|
174
174
|
});
|
|
175
175
|
var containerSchema = z.object({
|
|
176
176
|
capacity_weight: z.number().optional(),
|
|
177
|
-
|
|
177
|
+
holds_items: z.boolean().optional(),
|
|
178
178
|
pack_contents: z.array(z.string()).optional(),
|
|
179
|
+
pack_atomic: z.boolean().optional(),
|
|
179
180
|
capacity: containerCapacitySchema.optional()
|
|
180
181
|
});
|
|
181
182
|
var lightSchema = z.object({
|
|
@@ -206,6 +207,7 @@ var itemEntitySchema = z.object({
|
|
|
206
207
|
light: z.union([lightSchema, z.array(lightEntrySchema).nonempty()]).optional(),
|
|
207
208
|
cursed: z.boolean().optional(),
|
|
208
209
|
sentient: z.boolean().optional(),
|
|
210
|
+
tattoo: z.boolean().optional(),
|
|
209
211
|
// 54 docs carry a LIST of classes that may use the item as a focus
|
|
210
212
|
// (e.g. ["Druid", "Ranger"]); 26 carry a single string, 2 a boolean.
|
|
211
213
|
focus: z.union([z.boolean(), z.string(), z.array(z.string())]).optional(),
|
|
@@ -254,6 +256,8 @@ var itemEntitySchema = z.object({
|
|
|
254
256
|
// Carried by all 6,046 converter item docs, ALWAYS as the empty string today:
|
|
255
257
|
// `.min(1)` is forbidden here.
|
|
256
258
|
rendering_hint: z.string().optional(),
|
|
259
|
+
// The icon key (I3): a key of the renderer's icon set or a Lucide name; itemIconKey reads it first.
|
|
260
|
+
icon: z.string().optional(),
|
|
257
261
|
has_fluff: z.boolean().optional(),
|
|
258
262
|
has_fluff_images: z.boolean().optional(),
|
|
259
263
|
// Already `.optional()` at its source — never append a second one.
|
|
@@ -269,5 +273,6 @@ var itemEntitySchema = z.object({
|
|
|
269
273
|
|
|
270
274
|
export {
|
|
271
275
|
conditionSchema,
|
|
276
|
+
containerSchema,
|
|
272
277
|
itemEntitySchema
|
|
273
278
|
};
|