@archivist-gg/dnd5e 0.1.0 → 0.2.0
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 +4 -4
- package/dist/background/background.parser.js +3 -3
- package/dist/background/background.schema.js +2 -2
- package/dist/{chunk-FFULAF2P.js → chunk-2BWAID3Y.js} +2 -2
- package/dist/{chunk-FUK7QSN5.js → chunk-42Y5IJKT.js} +1 -1
- package/dist/{chunk-537BHVSH.js → chunk-4JHOHWBI.js} +1 -1
- package/dist/{chunk-ZLG6FQFB.js → chunk-5WQD3WNZ.js} +16 -1
- package/dist/{chunk-FEOB24KP.js → chunk-73HOFQQ5.js} +1 -1
- package/dist/{chunk-4SSDYJS2.js → chunk-7VJ6BOA5.js} +5 -1
- package/dist/{chunk-DABBCYTT.js → chunk-CZPMTQOY.js} +1 -1
- package/dist/{chunk-DRNZJNJP.js → chunk-DZXSWSBP.js} +1 -1
- package/dist/{chunk-RVYYKYFL.js → chunk-GE4TLPWM.js} +1 -1
- package/dist/{chunk-4C2KOKLF.js → chunk-K6Q5OUGK.js} +12 -0
- package/dist/{chunk-PMADYMUI.js → chunk-L7E2UT5A.js} +1 -1
- package/dist/{chunk-CDW7R2QT.js → chunk-NXSWH3AE.js} +4 -1
- package/dist/{chunk-IDTDACM6.js → chunk-PHQRGDRQ.js} +1 -1
- package/dist/{chunk-BAXWWGFJ.js → chunk-Q5K6LWBZ.js} +1 -1
- package/dist/chunk-R5SQHP2X.js +1092 -0
- package/dist/{chunk-Z6GXV2GO.js → chunk-TLYDBT5F.js} +1 -1
- package/dist/{chunk-QQ5W2AZP.js → chunk-TQZB4OCJ.js} +67 -12
- package/dist/{chunk-A7T5L7SS.js → chunk-TUIFSVLI.js} +1 -1
- package/dist/{chunk-XURS6Q6Q.js → chunk-V6SOFUJW.js} +19 -5
- package/dist/{chunk-Z4TL2V7S.js → chunk-VTYUBINW.js} +1 -1
- package/dist/{chunk-B7UXKNLD.js → chunk-W7HWMMBF.js} +1 -1
- package/dist/{chunk-SSXBYF3P.js → chunk-XLSVNUTK.js} +1 -1
- package/dist/{chunk-GIOH5JB5.js → chunk-XTIQWSFM.js} +1 -1
- package/dist/{chunk-PKC77VZP.js → chunk-ZZGEVJKX.js} +1 -1
- package/dist/class/class.codec.js +5 -5
- package/dist/class/class.parser.js +4 -4
- package/dist/class/class.schema.js +3 -3
- package/dist/feat/feat.codec.js +4 -4
- package/dist/feat/feat.parser.js +3 -3
- package/dist/feat/feat.schema.js +2 -2
- package/dist/index.js +622 -118
- package/dist/item/item.actions-map.d.ts +10 -3
- package/dist/item/item.actions-map.js +13 -8
- package/dist/item/item.codec.js +3 -3
- package/dist/item/item.parser.js +2 -2
- package/dist/item/item.schema.d.ts +13 -0
- package/dist/item/item.schema.js +1 -1
- package/dist/item/item.types.d.ts +17 -0
- package/dist/pc/pc.decision-engine.js +8 -1
- package/dist/pc/pc.equipment.d.ts +2 -1
- package/dist/pc/pc.equipment.js +9 -1
- package/dist/pc/pc.feature-effects.d.ts +31 -9
- package/dist/pc/pc.feature-effects.js +11 -1
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.js +8 -3
- package/dist/pc/pc.recalc.js +80 -62
- package/dist/pc/pc.resolver.d.ts +71 -1
- package/dist/pc/pc.resolver.js +21 -254
- package/dist/pc/pc.schema.d.ts +21 -0
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.types.d.ts +80 -1
- package/dist/race/race.codec.js +5 -5
- package/dist/race/race.parser.js +4 -4
- package/dist/race/race.schema.js +3 -3
- package/dist/schemas/choice-schema.js +1 -1
- package/dist/schemas/feature-schema.js +2 -2
- package/dist/subclass/subclass.codec.js +5 -5
- package/dist/subclass/subclass.parser.js +4 -4
- package/dist/subclass/subclass.schema.js +3 -3
- package/dist/types/choice.d.ts +5 -0
- package/dist/weapon/weapon-mastery.d.ts +12 -0
- package/package.json +1 -1
- package/dist/chunk-6PXE7T7C.js +0 -79
- package/dist/chunk-TJCNX6UZ.js +0 -521
|
@@ -33,9 +33,16 @@ export declare const ITEM_ACTIONS: Record<string, ItemAction>;
|
|
|
33
33
|
export declare function findItemAction(slug: string): ItemAction | undefined;
|
|
34
34
|
/**
|
|
35
35
|
* Resolve the ItemAction for an equipped entry.
|
|
36
|
-
* Priority:
|
|
37
|
-
*
|
|
36
|
+
* Priority: per-instance override > curated map > `itemType==="potion"`
|
|
37
|
+
* bonus-action default > null.
|
|
38
|
+
*
|
|
39
|
+
* `itemType` is the entity's `data.type` (from the registry, statically
|
|
40
|
+
* `unknown`); per the 2024 SRD, drinking/administering a potion is a Bonus
|
|
41
|
+
* Action, so an uncurated `type==="potion"` item still surfaces (curated oils
|
|
42
|
+
* mis-typed `"potion"` are pinned to "action" so this default cannot mislabel
|
|
43
|
+
* them). Returns null when no source supplies a cost (non-potion uncurated with
|
|
44
|
+
* no override).
|
|
38
45
|
*
|
|
39
46
|
* Accepts both bare and compendium-prefixed slugs (see `findItemAction`).
|
|
40
47
|
*/
|
|
41
|
-
export declare function resolveItemAction(slug: string, entry: EquipmentEntry): ItemAction | null;
|
|
48
|
+
export declare function resolveItemAction(slug: string, entry: EquipmentEntry, itemType?: unknown): ItemAction | null;
|
|
@@ -46,13 +46,19 @@ var ITEM_ACTIONS = {
|
|
|
46
46
|
// Magic weapons with activation actions (surface in items table only via override; weapons table is primary)
|
|
47
47
|
"sun-blade": { cost: "free", range: "self" },
|
|
48
48
|
// Potions / consumables
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"potion-of-
|
|
52
|
-
"potion-of-
|
|
49
|
+
// 2024 healing potions are a Bonus Action to drink/administer (curation still
|
|
50
|
+
// carries range/max_charges/recovery; the type=potion default covers uncurated ones).
|
|
51
|
+
"potion-of-healing": { cost: "bonus-action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
52
|
+
"potion-of-greater-healing": { cost: "bonus-action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
53
|
+
"potion-of-superior-healing": { cost: "bonus-action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
54
|
+
"potion-of-supreme-healing": { cost: "bonus-action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
53
55
|
"alchemists-fire": { cost: "action", range: "20 ft.", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
54
56
|
"holy-water": { cost: "action", range: "20 ft.", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
57
|
+
// Oils are APPLIED (minutes), not drunk: curated to "action" so the blanket
|
|
58
|
+
// type=potion → bonus-action default never mislabels these mis-typed items.
|
|
55
59
|
"oil-of-sharpness": { cost: "action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
60
|
+
"oil-of-etherealness": { cost: "action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
61
|
+
"oil-of-slipperiness": { cost: "action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } },
|
|
56
62
|
"dust-of-disappearance": { cost: "action", range: "self", max_charges: 1, recovery: { amount: "0", reset: "special" } }
|
|
57
63
|
};
|
|
58
64
|
function findItemAction(slug) {
|
|
@@ -62,14 +68,13 @@ function findItemAction(slug) {
|
|
|
62
68
|
const bare = slug.slice(underscore + 1);
|
|
63
69
|
return ITEM_ACTIONS[bare];
|
|
64
70
|
}
|
|
65
|
-
function resolveItemAction(slug, entry) {
|
|
66
|
-
var _a;
|
|
71
|
+
function resolveItemAction(slug, entry, itemType) {
|
|
72
|
+
var _a, _b;
|
|
67
73
|
const curated = (_a = findItemAction(slug)) != null ? _a : null;
|
|
68
74
|
const override = entry.overrides;
|
|
69
75
|
const overrideCost = override == null ? void 0 : override.action;
|
|
70
76
|
const overrideRange = override == null ? void 0 : override.range;
|
|
71
|
-
|
|
72
|
-
const cost = overrideCost != null ? overrideCost : curated == null ? void 0 : curated.cost;
|
|
77
|
+
const cost = (_b = overrideCost != null ? overrideCost : curated == null ? void 0 : curated.cost) != null ? _b : itemType === "potion" ? "bonus-action" : void 0;
|
|
73
78
|
if (!cost) return null;
|
|
74
79
|
return {
|
|
75
80
|
cost,
|
package/dist/item/item.codec.js
CHANGED
package/dist/item/item.parser.js
CHANGED
|
@@ -165,6 +165,19 @@ export declare const itemEntitySchema: z.ZodObject<{
|
|
|
165
165
|
description: z.ZodOptional<z.ZodString>;
|
|
166
166
|
entries: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
167
167
|
effects: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
168
|
+
damage_riders: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
169
|
+
amount: z.ZodString;
|
|
170
|
+
damage_type: z.ZodString;
|
|
171
|
+
applies_to: z.ZodOptional<z.ZodEnum<{
|
|
172
|
+
weapon: "weapon";
|
|
173
|
+
spell: "spell";
|
|
174
|
+
all: "all";
|
|
175
|
+
}>>;
|
|
176
|
+
condition: z.ZodOptional<z.ZodString>;
|
|
177
|
+
}, z.core.$strip>>>;
|
|
178
|
+
scroll_level: z.ZodOptional<z.ZodNumber>;
|
|
179
|
+
unidentified: z.ZodOptional<z.ZodBoolean>;
|
|
180
|
+
masked_category: z.ZodOptional<z.ZodString>;
|
|
168
181
|
raw: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
169
182
|
damage_dice: z.ZodOptional<z.ZodString>;
|
|
170
183
|
damage_type: z.ZodOptional<z.ZodString>;
|
package/dist/item/item.schema.js
CHANGED
|
@@ -97,6 +97,23 @@ export interface ItemEntity {
|
|
|
97
97
|
description?: string;
|
|
98
98
|
entries?: unknown[];
|
|
99
99
|
effects?: unknown[];
|
|
100
|
+
/** Structured additive on-hit damage riders (e.g. Flame Tongue "+2d6 fire",
|
|
101
|
+
* Wounding "+2d6 necrotic"). Read per-weapon in the equipment builder →
|
|
102
|
+
* AttackRow.damageRiders. `amount` is a dice/flat string. */
|
|
103
|
+
damage_riders?: Array<{
|
|
104
|
+
amount: string;
|
|
105
|
+
damage_type: string;
|
|
106
|
+
applies_to?: "weapon" | "spell" | "all";
|
|
107
|
+
condition?: string;
|
|
108
|
+
}>;
|
|
109
|
+
/** Spell-scroll casting level (e.g. 3 for a "Spell Scroll (3rd Level)"). */
|
|
110
|
+
scroll_level?: number;
|
|
111
|
+
/** Marks an item the player has not yet identified: the sheet shows the
|
|
112
|
+
* masked_category label instead of the item's true identity. */
|
|
113
|
+
unidentified?: boolean;
|
|
114
|
+
/** Generic category label shown for an unidentified item (e.g. "potion",
|
|
115
|
+
* "scroll", "wand") in place of its real name. */
|
|
116
|
+
masked_category?: string;
|
|
100
117
|
raw?: Record<string, unknown>;
|
|
101
118
|
damage_dice?: string;
|
|
102
119
|
damage_type?: string;
|
|
@@ -5,9 +5,16 @@ import {
|
|
|
5
5
|
collectChosenAbilityPoints,
|
|
6
6
|
collectChosenProficiencies,
|
|
7
7
|
wikilinkTailSlug
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-R5SQHP2X.js";
|
|
9
9
|
import "../chunk-BH6AMZVY.js";
|
|
10
|
+
import "../chunk-UC4FE5X3.js";
|
|
11
|
+
import "../chunk-IXZXFFFW.js";
|
|
12
|
+
import "../chunk-5XUXXAQJ.js";
|
|
10
13
|
import "../chunk-JEYQU3JT.js";
|
|
14
|
+
import "../chunk-DC74TZNA.js";
|
|
15
|
+
import "../chunk-3TRGRSCH.js";
|
|
16
|
+
import "../chunk-J2RYSZMQ.js";
|
|
17
|
+
import "../chunk-NAEPSZAM.js";
|
|
11
18
|
import "../chunk-WP2CX2JO.js";
|
|
12
19
|
export {
|
|
13
20
|
__matchesFilterForTest,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EntityRegistry } from "@archivist-gg/core";
|
|
2
2
|
import type { Ability } from "@archivist-gg/dnd5e";
|
|
3
3
|
import type { AppliedBonuses, DerivedEquipment, ResolvedCharacter, ProficiencySet } from "./pc.types.js";
|
|
4
|
+
import type { WeaponAbilityOverride } from "./pc.feature-effects.js";
|
|
4
5
|
interface ProficienciesForQuery {
|
|
5
6
|
armor: ProficiencySet;
|
|
6
7
|
weapons: ProficiencySet;
|
|
@@ -8,5 +9,5 @@ interface ProficienciesForQuery {
|
|
|
8
9
|
}
|
|
9
10
|
export declare function emptyAppliedBonuses(): AppliedBonuses;
|
|
10
11
|
export declare function computeAppliedBonuses(resolved: ResolvedCharacter, _profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[]): AppliedBonuses;
|
|
11
|
-
export declare function computeSlotsAndAttacks(resolved: ResolvedCharacter, mods: Record<Ability, number>, profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[], proficiencyBonus: number,
|
|
12
|
+
export declare function computeSlotsAndAttacks(resolved: ResolvedCharacter, mods: Record<Ability, number>, profs: ProficienciesForQuery, registry: EntityRegistry, warnings: string[], proficiencyBonus: number, weaponAbilities?: WeaponAbilityOverride[], weaponMasteries?: string[]): DerivedEquipment;
|
|
12
13
|
export {};
|
package/dist/pc/pc.equipment.js
CHANGED
|
@@ -2,12 +2,20 @@ import {
|
|
|
2
2
|
computeAppliedBonuses,
|
|
3
3
|
computeSlotsAndAttacks,
|
|
4
4
|
emptyAppliedBonuses
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-TQZB4OCJ.js";
|
|
6
|
+
import "../chunk-R5SQHP2X.js";
|
|
7
|
+
import "../chunk-BH6AMZVY.js";
|
|
6
8
|
import "../chunk-UC4FE5X3.js";
|
|
9
|
+
import "../chunk-IXZXFFFW.js";
|
|
10
|
+
import "../chunk-5XUXXAQJ.js";
|
|
11
|
+
import "../chunk-JEYQU3JT.js";
|
|
7
12
|
import "../chunk-LWFTHJIE.js";
|
|
8
13
|
import "../chunk-DNAJRMNN.js";
|
|
9
14
|
import "../chunk-DC74TZNA.js";
|
|
10
15
|
import "../chunk-3TRGRSCH.js";
|
|
16
|
+
import "../chunk-J2RYSZMQ.js";
|
|
17
|
+
import "../chunk-NAEPSZAM.js";
|
|
18
|
+
import "../chunk-WP2CX2JO.js";
|
|
11
19
|
export {
|
|
12
20
|
computeAppliedBonuses,
|
|
13
21
|
computeSlotsAndAttacks,
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
import type { SenseType } from "@archivist-gg/dnd5e/types/feature-effect";
|
|
2
2
|
import type { Ability } from "@archivist-gg/dnd5e";
|
|
3
|
-
import type { ResolvedFeature, RollModifierEntry } from "./pc.types.js";
|
|
3
|
+
import type { DamageRider, ResolvedFeature, RollModifierEntry } from "./pc.types.js";
|
|
4
|
+
/**
|
|
5
|
+
* A melee-attack ability override from a `weapon-ability` effect. `weaponSlugs`
|
|
6
|
+
* (bare, namespace-stripped) scopes the override to matching weapon types only;
|
|
7
|
+
* empty/absent `weaponSlugs` = GLOBAL (applies to every melee weapon). The
|
|
8
|
+
* `"spellcasting"` sentinel is NOT stored here — it is resolved against the
|
|
9
|
+
* caster ability in recalc and prepended as a global.
|
|
10
|
+
*/
|
|
11
|
+
export interface WeaponAbilityOverride {
|
|
12
|
+
ability: Ability;
|
|
13
|
+
weaponSlugs?: string[];
|
|
14
|
+
}
|
|
4
15
|
/**
|
|
5
16
|
* Aggregated passive feature effects (effects-application engine).
|
|
6
17
|
* One pure scan over resolved.features[].feature.effects[]. Merge semantics
|
|
7
18
|
* mirror pc.conditions mergePartial: numbers add, each sense range takes max,
|
|
8
|
-
* lists union case-insensitively. apply-condition
|
|
9
|
-
*
|
|
10
|
-
*
|
|
19
|
+
* lists union case-insensitively. apply-condition is action time and
|
|
20
|
+
* intentionally not aggregated; `damage-bonus` folds into damageBonuses (additive
|
|
21
|
+
* on-hit riders); `while`-gated immune-condition entries are skipped entirely
|
|
22
|
+
* (conditional effects are a named deferral).
|
|
11
23
|
*/
|
|
12
24
|
export interface FeatureEffectTotals {
|
|
13
25
|
initiative_bonus: number;
|
|
@@ -46,12 +58,15 @@ export interface FeatureEffectTotals {
|
|
|
46
58
|
weapons: string[];
|
|
47
59
|
};
|
|
48
60
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
61
|
+
* Melee-attack ability overrides (Hexblade "Lies", MCDM Illrigger scoped
|
|
62
|
+
* "Lies", etc.), in fold order. Each carries an optional `weaponSlugs` scope
|
|
63
|
+
* (bare slugs) — absent/empty = GLOBAL (every melee weapon). The
|
|
64
|
+
* `"spellcasting"` sentinel is excluded here (no caster context in the fold);
|
|
65
|
+
* recalc resolves it and prepends the resolved global so it wins over concrete
|
|
66
|
+
* globals. recalc threads this list into attack computation, where a
|
|
67
|
+
* scoped-match wins over a global for the matching weapon. [] = no override.
|
|
53
68
|
*/
|
|
54
|
-
|
|
69
|
+
weaponAbilities: WeaponAbilityOverride[];
|
|
55
70
|
/**
|
|
56
71
|
* Order-preserving list of structured advantage/disadvantage entries from
|
|
57
72
|
* `roll-modifier` effects. Pass-through (no dedupe/merge); each entry is
|
|
@@ -79,6 +94,13 @@ export interface FeatureEffectTotals {
|
|
|
79
94
|
* non-empty, so untouched attack rows keep `attackNotes: undefined`.
|
|
80
95
|
*/
|
|
81
96
|
attackNotes: string[];
|
|
97
|
+
/**
|
|
98
|
+
* Additive on-hit damage riders from `damage-bonus` effects with
|
|
99
|
+
* `applies_to` weapon/all (spell-only ignored — no spell surface). Each is
|
|
100
|
+
* labeled with the owning feature's name. recalc merges these onto every
|
|
101
|
+
* weapon AttackRow's `damageRiders`.
|
|
102
|
+
*/
|
|
103
|
+
damageBonuses: DamageRider[];
|
|
82
104
|
}
|
|
83
105
|
export declare function emptyFeatureEffectTotals(): FeatureEffectTotals;
|
|
84
106
|
/**
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computeFeatureEffects,
|
|
3
3
|
emptyFeatureEffectTotals
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-V6SOFUJW.js";
|
|
5
|
+
import "../chunk-R5SQHP2X.js";
|
|
6
|
+
import "../chunk-BH6AMZVY.js";
|
|
7
|
+
import "../chunk-UC4FE5X3.js";
|
|
8
|
+
import "../chunk-IXZXFFFW.js";
|
|
9
|
+
import "../chunk-5XUXXAQJ.js";
|
|
10
|
+
import "../chunk-JEYQU3JT.js";
|
|
11
|
+
import "../chunk-DC74TZNA.js";
|
|
12
|
+
import "../chunk-3TRGRSCH.js";
|
|
13
|
+
import "../chunk-J2RYSZMQ.js";
|
|
14
|
+
import "../chunk-NAEPSZAM.js";
|
|
5
15
|
import "../chunk-WP2CX2JO.js";
|
|
6
16
|
export {
|
|
7
17
|
computeFeatureEffects,
|
package/dist/pc/pc.parser.js
CHANGED
package/dist/pc/pc.pools.js
CHANGED
|
@@ -2,11 +2,16 @@ import {
|
|
|
2
2
|
levelPrereqMax,
|
|
3
3
|
resolveAllPools,
|
|
4
4
|
resolvePool
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-5XUXXAQJ.js";
|
|
7
|
-
import "../chunk-TJCNX6UZ.js";
|
|
5
|
+
} from "../chunk-R5SQHP2X.js";
|
|
8
6
|
import "../chunk-BH6AMZVY.js";
|
|
7
|
+
import "../chunk-UC4FE5X3.js";
|
|
8
|
+
import "../chunk-IXZXFFFW.js";
|
|
9
|
+
import "../chunk-5XUXXAQJ.js";
|
|
9
10
|
import "../chunk-JEYQU3JT.js";
|
|
11
|
+
import "../chunk-DC74TZNA.js";
|
|
12
|
+
import "../chunk-3TRGRSCH.js";
|
|
13
|
+
import "../chunk-J2RYSZMQ.js";
|
|
14
|
+
import "../chunk-NAEPSZAM.js";
|
|
10
15
|
import "../chunk-WP2CX2JO.js";
|
|
11
16
|
export {
|
|
12
17
|
levelPrereqMax,
|
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
computeSpellLimits,
|
|
3
|
-
deriveSpellSlots,
|
|
4
|
-
resolveSpellcasting
|
|
5
|
-
} from "../chunk-IXZXFFFW.js";
|
|
6
|
-
import "../chunk-5XUXXAQJ.js";
|
|
7
1
|
import {
|
|
8
2
|
computeConditionEffects
|
|
9
3
|
} from "../chunk-R2ZV233X.js";
|
|
10
|
-
import {
|
|
11
|
-
collectChosenAbilityPoints,
|
|
12
|
-
collectChosenProficiencies
|
|
13
|
-
} from "../chunk-TJCNX6UZ.js";
|
|
14
|
-
import "../chunk-BH6AMZVY.js";
|
|
15
|
-
import "../chunk-JEYQU3JT.js";
|
|
16
4
|
import {
|
|
17
5
|
computeAppliedBonuses,
|
|
18
6
|
computeSlotsAndAttacks,
|
|
19
7
|
emptyAppliedBonuses
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import "../chunk-UC4FE5X3.js";
|
|
8
|
+
} from "../chunk-TQZB4OCJ.js";
|
|
22
9
|
import {
|
|
23
10
|
computeFeatureEffects
|
|
24
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-V6SOFUJW.js";
|
|
12
|
+
import {
|
|
13
|
+
collectChosenAbilityPoints,
|
|
14
|
+
collectChosenProficiencies
|
|
15
|
+
} from "../chunk-R5SQHP2X.js";
|
|
16
|
+
import "../chunk-BH6AMZVY.js";
|
|
17
|
+
import "../chunk-UC4FE5X3.js";
|
|
18
|
+
import {
|
|
19
|
+
computeSpellLimits,
|
|
20
|
+
deriveSpellSlots,
|
|
21
|
+
resolveSpellcasting
|
|
22
|
+
} from "../chunk-IXZXFFFW.js";
|
|
23
|
+
import "../chunk-5XUXXAQJ.js";
|
|
24
|
+
import "../chunk-JEYQU3JT.js";
|
|
25
25
|
import "../chunk-LWFTHJIE.js";
|
|
26
26
|
import "../chunk-DNAJRMNN.js";
|
|
27
27
|
import "../chunk-DC74TZNA.js";
|
|
@@ -362,24 +362,26 @@ function computeProficiencies(resolved) {
|
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
364
|
function recalc(resolved, registry) {
|
|
365
|
-
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
|
|
365
|
+
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;
|
|
366
366
|
const warnings = [];
|
|
367
367
|
const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
|
|
368
368
|
const chosenProfs = collectChosenProficiencies(resolved);
|
|
369
369
|
const activeBuffs = new Set((_b = resolved.state.active_buffs) != null ? _b : []);
|
|
370
370
|
const buffFeatures = [];
|
|
371
|
+
const pushBoon = (item, pool) => {
|
|
372
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
373
|
+
const e = item.entity;
|
|
374
|
+
if (!e || ((_b2 = (_a2 = e.effects) == null ? void 0 : _a2.length) != null ? _b2 : 0) === 0) return;
|
|
375
|
+
buffFeatures.push({
|
|
376
|
+
feature: { id: item.slug, name: e.name, activatable: (_c2 = e.activatable) != null ? _c2 : false, effects: e.effects },
|
|
377
|
+
// source is inert for the fold; attribute to the pool's owning class
|
|
378
|
+
// (never a hardcoded class) so the generic engine carries no homebrew name.
|
|
379
|
+
source: { kind: "class", slug: (_f2 = (_e2 = (_d2 = resolved.classes[pool.classIndex]) == null ? void 0 : _d2.entity) == null ? void 0 : _e2.slug) != null ? _f2 : pool.id, level: pool.anchorLevel }
|
|
380
|
+
});
|
|
381
|
+
};
|
|
371
382
|
for (const pool of (_c = resolved.pools) != null ? _c : []) {
|
|
372
|
-
for (const sel of (_d = pool.selected) != null ? _d : [])
|
|
373
|
-
|
|
374
|
-
if ((e == null ? void 0 : e.activatable) && ((_f = (_e = e.effects) == null ? void 0 : _e.length) != null ? _f : 0) > 0) {
|
|
375
|
-
buffFeatures.push({
|
|
376
|
-
feature: { id: sel.slug, name: e.name, activatable: true, effects: e.effects },
|
|
377
|
-
// source is inert for the fold; attribute to the pool's owning class
|
|
378
|
-
// (never a hardcoded class) so the generic engine carries no homebrew name.
|
|
379
|
-
source: { kind: "class", slug: (_i = (_h = (_g = resolved.classes[pool.classIndex]) == null ? void 0 : _g.entity) == null ? void 0 : _h.slug) != null ? _i : pool.id, level: pool.anchorLevel }
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
+
for (const sel of (_d = pool.selected) != null ? _d : []) pushBoon(sel, pool);
|
|
384
|
+
for (const g of (_e = pool.grants) != null ? _e : []) pushBoon(g, pool);
|
|
383
385
|
}
|
|
384
386
|
const featureEffects = computeFeatureEffects([...resolved.features, ...buffFeatures], { activeBuffs });
|
|
385
387
|
const profsForApply = computeProficiencies(resolved);
|
|
@@ -443,19 +445,20 @@ function recalc(resolved, registry) {
|
|
|
443
445
|
resolved.definition.edition,
|
|
444
446
|
scores
|
|
445
447
|
);
|
|
446
|
-
const firstClass = (
|
|
447
|
-
const saveProfs = new Set((
|
|
448
|
+
const firstClass = (_g = (_f = resolved.classes[0]) == null ? void 0 : _f.entity) != null ? _g : null;
|
|
449
|
+
const saveProfs = new Set((_h = firstClass == null ? void 0 : firstClass.saving_throws) != null ? _h : []);
|
|
448
450
|
for (const ab of featureEffects.proficiencies.saves) saveProfs.add(ab);
|
|
449
451
|
const saves = {};
|
|
450
452
|
for (const ab of ABILITY_KEYS) {
|
|
451
|
-
const override = (
|
|
452
|
-
const prof = (
|
|
453
|
+
const override = (_i = overrides.saves) == null ? void 0 : _i[ab];
|
|
454
|
+
const prof = (_j = override == null ? void 0 : override.proficient) != null ? _j : saveProfs.has(ab);
|
|
453
455
|
const derivedBonus = savingThrow(scores[ab], prof, proficiencyBonus) + applied.save_bonus + conditionEffects.d20_test_penalty;
|
|
454
|
-
const bonus = (
|
|
456
|
+
const bonus = (_k = override == null ? void 0 : override.bonus) != null ? _k : derivedBonus;
|
|
455
457
|
saves[ab] = { bonus, proficient: prof };
|
|
456
458
|
}
|
|
457
459
|
const profSet = /* @__PURE__ */ new Set([
|
|
458
460
|
...resolved.definition.skills.proficient,
|
|
461
|
+
...(_m = (_l = resolved.background) == null ? void 0 : _l.skill_proficiencies) != null ? _m : [],
|
|
459
462
|
...chosenProfs.skills,
|
|
460
463
|
...featureEffects.proficiencies.skills
|
|
461
464
|
]);
|
|
@@ -464,9 +467,9 @@ function recalc(resolved, registry) {
|
|
|
464
467
|
for (const skill of ALL_SKILLS) {
|
|
465
468
|
const skillKey = skillSlugFromDisplay(skill);
|
|
466
469
|
const ab = SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];
|
|
467
|
-
const override = (
|
|
468
|
-
const tri = (
|
|
469
|
-
const bonus = (
|
|
470
|
+
const override = (_n = overrides.skills) == null ? void 0 : _n[skillKey];
|
|
471
|
+
const tri = (_o = override == null ? void 0 : override.proficiency) != null ? _o : expSet.has(skillKey) ? "expertise" : profSet.has(skillKey) ? "proficient" : "none";
|
|
472
|
+
const bonus = (_p = override == null ? void 0 : override.bonus) != null ? _p : skillBonus(scores[ab], tri, proficiencyBonus) + conditionEffects.d20_test_penalty;
|
|
470
473
|
skills[skillKey] = {
|
|
471
474
|
bonus,
|
|
472
475
|
proficiency: tri,
|
|
@@ -477,16 +480,16 @@ function recalc(resolved, registry) {
|
|
|
477
480
|
const investigationTri = skills.investigation.proficiency;
|
|
478
481
|
const insightTri = skills.insight.proficiency;
|
|
479
482
|
const passives = {
|
|
480
|
-
perception: (
|
|
481
|
-
investigation: (
|
|
482
|
-
insight: (
|
|
483
|
+
perception: (_r = (_q = overrides.passives) == null ? void 0 : _q.perception) != null ? _r : passivePerception(scores.wis, perceptionTri, proficiencyBonus),
|
|
484
|
+
investigation: (_t = (_s = overrides.passives) == null ? void 0 : _s.investigation) != null ? _t : passive(scores.int, investigationTri, proficiencyBonus),
|
|
485
|
+
insight: (_v = (_u = overrides.passives) == null ? void 0 : _u.insight) != null ? _v : passive(scores.wis, insightTri, proficiencyBonus)
|
|
483
486
|
};
|
|
484
487
|
const hpMaxDerived = multiclassMaxHP(resolved.classes, mods.con) + featureEffects.hp_per_level_bonus * totalLevel;
|
|
485
488
|
const hpMaxAfterConditions = Math.floor(hpMaxDerived * conditionEffects.hp_max_multiplier);
|
|
486
|
-
const hpMax = (
|
|
489
|
+
const hpMax = (_x = (_w = overrides.hp) == null ? void 0 : _w.max) != null ? _x : hpMaxAfterConditions;
|
|
487
490
|
const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature" }));
|
|
488
491
|
const sumTerms = (terms) => terms.reduce((s, t) => s + t.amount, 0);
|
|
489
|
-
|
|
492
|
+
const weaponAbilities = [...featureEffects.weaponAbilities];
|
|
490
493
|
const wantsSpellcasting = resolved.features.some((rf) => {
|
|
491
494
|
var _a2;
|
|
492
495
|
return ((_a2 = rf.feature.effects) != null ? _a2 : []).some((e) => e.kind === "weapon-ability" && e.ability === "spellcasting");
|
|
@@ -501,14 +504,14 @@ function recalc(resolved, registry) {
|
|
|
501
504
|
break;
|
|
502
505
|
}
|
|
503
506
|
}
|
|
504
|
-
if (primaryCasterAbility)
|
|
507
|
+
if (primaryCasterAbility) weaponAbilities.unshift({ ability: primaryCasterAbility });
|
|
505
508
|
}
|
|
506
509
|
let derivedEquipment = null;
|
|
507
510
|
let acDerived;
|
|
508
511
|
let acBreakdownDerived = [];
|
|
509
512
|
let acInformationalDerived = [];
|
|
510
513
|
if (registry) {
|
|
511
|
-
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus,
|
|
514
|
+
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (_y = resolved.weaponMasteries) != null ? _y : []);
|
|
512
515
|
if (derivedEquipment.equippedSlots.armor) {
|
|
513
516
|
const featTerms = featureAcTermsFor(true);
|
|
514
517
|
acDerived = derivedEquipment.ac + sumTerms(featTerms);
|
|
@@ -531,16 +534,16 @@ function recalc(resolved, registry) {
|
|
|
531
534
|
acDerived = total + sumTerms(featTerms);
|
|
532
535
|
acBreakdownDerived = [...terms, ...featTerms];
|
|
533
536
|
}
|
|
534
|
-
const ac = (
|
|
537
|
+
const ac = (_z = overrides.ac) != null ? _z : acDerived;
|
|
535
538
|
const additiveSpeed = speedFromRace(resolved) + applied.speed_bonuses.walk + featureEffects.speed_walk_bonus;
|
|
536
539
|
const baseSpeed = Math.max(featureEffects.speed_walk_set, additiveSpeed);
|
|
537
540
|
const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
|
|
538
541
|
const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
|
|
539
|
-
const speed = (
|
|
542
|
+
const speed = (_A = overrides.speed) != null ? _A : conditionSpeed;
|
|
540
543
|
if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
|
|
541
|
-
const init = (
|
|
544
|
+
const init = (_B = overrides.initiative) != null ? _B : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
|
|
542
545
|
const senses = {
|
|
543
|
-
darkvision: Math.max((
|
|
546
|
+
darkvision: Math.max((_E = (_D = (_C = resolved.race) == null ? void 0 : _C.vision) == null ? void 0 : _D.darkvision) != null ? _E : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
|
|
544
547
|
blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
|
|
545
548
|
tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
|
|
546
549
|
truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
|
|
@@ -558,8 +561,8 @@ function recalc(resolved, registry) {
|
|
|
558
561
|
classSlug: c.entity.slug,
|
|
559
562
|
className: c.entity.name,
|
|
560
563
|
ability: profile.ability,
|
|
561
|
-
saveDC: (
|
|
562
|
-
attackBonus: (
|
|
564
|
+
saveDC: (_G = (_F = overrides.spellcasting) == null ? void 0 : _F.saveDC) != null ? _G : dc,
|
|
565
|
+
attackBonus: (_I = (_H = overrides.spellcasting) == null ? void 0 : _H.attackBonus) != null ? _I : atk,
|
|
563
566
|
casterType: profile.casterType,
|
|
564
567
|
preparation: profile.preparation
|
|
565
568
|
});
|
|
@@ -571,24 +574,33 @@ function recalc(resolved, registry) {
|
|
|
571
574
|
saveDC: spellcastingClasses[0].saveDC,
|
|
572
575
|
attackBonus: spellcastingClasses[0].attackBonus
|
|
573
576
|
} : null;
|
|
577
|
+
const abilitySpellcasting = {};
|
|
578
|
+
for (const s of resolved.spells) {
|
|
579
|
+
const ab = s.ability;
|
|
580
|
+
if (!ab || abilitySpellcasting[ab]) continue;
|
|
581
|
+
abilitySpellcasting[ab] = {
|
|
582
|
+
saveDC: saveDC(scores[ab], proficiencyBonus) + applied.spell_save_dc,
|
|
583
|
+
attackBonus: attackBonus(scores[ab], proficiencyBonus) + applied.spell_attack
|
|
584
|
+
};
|
|
585
|
+
}
|
|
574
586
|
const derivedSlots = deriveSpellSlots(slotInputs);
|
|
575
587
|
const spellLimits = computeSpellLimits(limitInputs);
|
|
576
588
|
const defenses = {
|
|
577
589
|
resistances: dedupeDefenseList([
|
|
578
|
-
(
|
|
590
|
+
(_K = (_J = resolved.definition.defenses) == null ? void 0 : _J.resistances) != null ? _K : [],
|
|
579
591
|
applied.defenses.resistances,
|
|
580
592
|
featureEffects.resistances
|
|
581
593
|
]),
|
|
582
594
|
immunities: dedupeDefenseList([
|
|
583
|
-
(
|
|
595
|
+
(_M = (_L = resolved.definition.defenses) == null ? void 0 : _L.immunities) != null ? _M : [],
|
|
584
596
|
applied.defenses.immunities
|
|
585
597
|
]),
|
|
586
598
|
vulnerabilities: dedupeDefenseList([
|
|
587
|
-
(
|
|
599
|
+
(_O = (_N = resolved.definition.defenses) == null ? void 0 : _N.vulnerabilities) != null ? _O : [],
|
|
588
600
|
applied.defenses.vulnerabilities
|
|
589
601
|
]),
|
|
590
602
|
condition_immunities: dedupeDefenseList([
|
|
591
|
-
(
|
|
603
|
+
(_Q = (_P = resolved.definition.defenses) == null ? void 0 : _P.condition_immunities) != null ? _Q : [],
|
|
592
604
|
applied.defenses.condition_immunities,
|
|
593
605
|
featureEffects.condition_immunities
|
|
594
606
|
])
|
|
@@ -613,6 +625,7 @@ function recalc(resolved, registry) {
|
|
|
613
625
|
initiative: init,
|
|
614
626
|
spellcasting,
|
|
615
627
|
spellcastingClasses,
|
|
628
|
+
abilitySpellcasting,
|
|
616
629
|
derivedSpellSlots: derivedSlots.standard,
|
|
617
630
|
pactMagic: derivedSlots.pact,
|
|
618
631
|
spellLimits,
|
|
@@ -630,16 +643,21 @@ function recalc(resolved, registry) {
|
|
|
630
643
|
// untouched rows keep `critRange`/`attackNotes` ABSENT (not 20 / not []).
|
|
631
644
|
// crit-range: folded weapon crit threshold, only when an effect lowered it.
|
|
632
645
|
// attackNotes: reroll-damage / attack-rule captions, only when non-empty.
|
|
633
|
-
attacks: ((
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
646
|
+
attacks: ((_R = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _R : []).map((a) => {
|
|
647
|
+
var _a2;
|
|
648
|
+
const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses];
|
|
649
|
+
return {
|
|
650
|
+
...a,
|
|
651
|
+
toHit: a.toHit + conditionEffects.d20_test_penalty,
|
|
652
|
+
...featureEffects.critRange < 20 ? { critRange: featureEffects.critRange } : {},
|
|
653
|
+
...featureEffects.attackNotes.length ? { attackNotes: featureEffects.attackNotes } : {},
|
|
654
|
+
...riders.length ? { damageRiders: riders } : {}
|
|
655
|
+
};
|
|
656
|
+
}),
|
|
657
|
+
equippedSlots: (_S = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _S : {},
|
|
658
|
+
carriedWeight: (_T = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _T : 0,
|
|
659
|
+
attunementUsed: (_U = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _U : 0,
|
|
660
|
+
attunementLimit: (_W = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _W : (_V = overrides.attunement_limit) != null ? _V : 3,
|
|
643
661
|
conditionEffects,
|
|
644
662
|
rollModifiers: featureEffects.rollModifiers
|
|
645
663
|
};
|