@archivist-gg/dnd5e 0.3.1 → 0.3.5
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 +25 -6
- package/dist/armor/armor.codec.js +4 -3
- package/dist/armor/armor.parser.js +3 -2
- package/dist/armor/armor.schema.d.ts +4 -0
- package/dist/armor/armor.schema.js +2 -1
- package/dist/armor/armor.types.d.ts +8 -0
- package/dist/background/background.codec.js +7 -6
- package/dist/background/background.parser.js +6 -5
- package/dist/background/background.schema.d.ts +26 -0
- package/dist/background/background.schema.js +5 -4
- package/dist/background/background.types.d.ts +22 -0
- package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
- package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
- package/dist/chunk-2FRUSVZS.js +489 -0
- package/dist/chunk-2VDTW7QO.js +1580 -0
- package/dist/{chunk-ZZGEVJKX.js → chunk-3JOTQW7A.js} +1 -1
- package/dist/{chunk-5ZBE4CWV.js → chunk-3PZHBLFG.js} +1 -1
- package/dist/chunk-4U55VNC7.js +22 -0
- package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
- package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
- package/dist/{chunk-42Y5IJKT.js → chunk-5RKLL2AD.js} +5 -1
- package/dist/{chunk-SE7AZDR3.js → chunk-63XQXPZL.js} +29 -3
- package/dist/{chunk-4F6AIZ36.js → chunk-6BFWZW6T.js} +1 -1
- package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
- package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
- package/dist/chunk-6X2NV665.js +33 -0
- package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
- package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
- package/dist/{chunk-TLYDBT5F.js → chunk-CGRLQ34U.js} +64 -7
- package/dist/chunk-CJYCVNW2.js +7 -0
- package/dist/{chunk-XLSVNUTK.js → chunk-CV5XDJKU.js} +1 -1
- package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
- package/dist/{chunk-6IRYTM5V.js → chunk-DPUJDOKV.js} +119 -28
- package/dist/{chunk-GE4TLPWM.js → chunk-EHDATXP7.js} +1 -1
- package/dist/chunk-EVMUJYUD.js +195 -0
- package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
- package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
- package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
- package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
- package/dist/chunk-IUAAXXNO.js +58 -0
- package/dist/{chunk-NXSWH3AE.js → chunk-IWRVOCT5.js} +1 -1
- package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
- package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
- package/dist/{chunk-XTIQWSFM.js → chunk-KADJZGZY.js} +1 -1
- package/dist/{chunk-L7E2UT5A.js → chunk-KK33PIDN.js} +5 -1
- package/dist/chunk-KPEJMNRD.js +302 -0
- package/dist/chunk-KU3YLF6D.js +106 -0
- package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
- package/dist/chunk-LVQLWRCU.js +15 -0
- package/dist/chunk-MI7P3NX3.js +161 -0
- package/dist/{chunk-PHQRGDRQ.js → chunk-N3A5ICBO.js} +5 -1
- package/dist/chunk-O4SRD3J5.js +165 -0
- package/dist/chunk-OAXWSVJB.js +81 -0
- package/dist/chunk-OZP6JFGT.js +162 -0
- package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
- package/dist/chunk-PP2UHLBA.js +50 -0
- package/dist/chunk-PVCEA4HZ.js +6 -0
- package/dist/{chunk-RSDRMH54.js → chunk-RF4TYCA2.js} +1 -1
- package/dist/chunk-RLGQ5PZZ.js +16 -0
- package/dist/chunk-RVXC6ZHY.js +89 -0
- package/dist/chunk-S7REMWW4.js +21 -0
- package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
- package/dist/chunk-TOM66P2P.js +38 -0
- package/dist/chunk-UA5KS2PL.js +26 -0
- package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
- package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
- package/dist/{chunk-BIK4DFWK.js → chunk-ULCQ73LA.js} +1 -1
- package/dist/{chunk-2BWAID3Y.js → chunk-UMWIPLLM.js} +29 -3
- package/dist/chunk-UQ3ZFCWD.js +178 -0
- package/dist/chunk-UXPGW4TI.js +101 -0
- package/dist/chunk-V2MJE6NC.js +133 -0
- package/dist/{chunk-D3CLOBE3.js → chunk-V373TRJE.js} +48 -10
- package/dist/chunk-VQAXTIBW.js +100 -0
- package/dist/chunk-W74BCA7V.js +159 -0
- package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
- package/dist/{chunk-MDEJHMKK.js → chunk-WHVLNFTG.js} +26 -5
- package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
- package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
- package/dist/chunk-X3D6LXUU.js +185 -0
- package/dist/chunk-XJ2F2WO6.js +8 -0
- package/dist/{chunk-73HOFQQ5.js → chunk-Y4AGLCY6.js} +1 -1
- package/dist/chunk-YBLDE5CG.js +42 -0
- package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
- package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
- package/dist/class/class.codec.js +12 -9
- package/dist/class/class.parser.js +11 -8
- package/dist/class/class.schema.d.ts +55 -3
- package/dist/class/class.schema.js +9 -7
- package/dist/class/class.types.d.ts +48 -3
- package/dist/condition/condition.codec.d.ts +9 -0
- package/dist/condition/condition.entity-type.d.ts +2 -0
- package/dist/condition/condition.parser.d.ts +13 -0
- package/dist/condition/condition.parser.js +7 -0
- package/dist/condition/condition.schema.d.ts +29 -0
- package/dist/condition/condition.types.d.ts +15 -0
- package/dist/condition/condition.types.js +0 -0
- package/dist/dnd/constants.d.ts +22 -0
- package/dist/dnd/constants.js +9 -3
- package/dist/dnd/formula-tags.js +2 -2
- package/dist/dnd/math.d.ts +26 -0
- package/dist/dnd/math.js +12 -2
- package/dist/dnd/prose-tags.js +1 -1
- package/dist/dnd/resource-formula.d.ts +36 -10
- package/dist/dnd/resource-formula.js +10 -155
- package/dist/dnd/srd-tag-converter.js +3 -3
- package/dist/dnd/tag-grammar.js +1 -1
- package/dist/dnd/warn-once.d.ts +2 -0
- package/dist/dnd/warn-once.js +8 -0
- package/dist/entities/base-item-resolver.js +2 -2
- package/dist/entities/slug.d.ts +13 -0
- package/dist/entities/slug.js +5 -3
- package/dist/entities/wikilink-display.d.ts +3 -0
- package/dist/entities/wikilink-display.js +10 -0
- package/dist/feat/feat.category-codes.d.ts +32 -0
- package/dist/feat/feat.category-codes.js +14 -0
- package/dist/feat/feat.codec.js +7 -5
- package/dist/feat/feat.parser.js +6 -4
- package/dist/feat/feat.schema.d.ts +239 -0
- package/dist/feat/feat.schema.js +5 -3
- package/dist/feat/feat.types.d.ts +37 -1
- package/dist/index.js +2033 -6907
- package/dist/item/item.codec.js +4 -3
- package/dist/item/item.enrichment.js +4 -4
- package/dist/item/item.parser.js +3 -2
- package/dist/item/item.schema.d.ts +69 -3
- package/dist/item/item.schema.js +2 -1
- package/dist/item/item.types.d.ts +69 -3
- package/dist/monster/monster.codec.d.ts +7 -6
- package/dist/monster/monster.enrichment.js +4 -4
- package/dist/monster/monster.format.d.ts +135 -0
- package/dist/monster/monster.format.js +78 -0
- package/dist/monster/monster.parser.d.ts +6 -1
- package/dist/monster/monster.parser.js +10 -1
- package/dist/monster/monster.schema.d.ts +369 -0
- package/dist/monster/monster.schema.js +34 -0
- package/dist/monster/monster.types.d.ts +200 -14
- package/dist/optional-feature/optional-feature.codec.js +6 -5
- package/dist/optional-feature/optional-feature.parser.js +5 -4
- package/dist/optional-feature/optional-feature.schema.d.ts +185 -0
- package/dist/optional-feature/optional-feature.schema.js +4 -3
- package/dist/pack.d.ts +1 -1
- package/dist/pc/conditions.constants.d.ts +0 -1
- package/dist/pc/conditions.constants.js +1 -3
- package/dist/pc/decision-recognizer.js +1 -1
- package/dist/pc/pc.additional-spells.d.ts +47 -0
- package/dist/pc/pc.additional-spells.js +23 -0
- package/dist/pc/pc.asi-flatten.d.ts +18 -0
- package/dist/pc/pc.decision-engine.d.ts +105 -17
- package/dist/pc/pc.decision-engine.js +28 -12
- package/dist/pc/pc.defense-normalize.d.ts +11 -0
- package/dist/pc/pc.defense-normalize.js +6 -0
- package/dist/pc/pc.equipment.d.ts +31 -2
- package/dist/pc/pc.equipment.js +12 -8
- package/dist/pc/pc.feature-effects.d.ts +234 -11
- package/dist/pc/pc.feature-effects.js +21 -5
- package/dist/pc/pc.parser.js +2 -2
- package/dist/pc/pc.pools.d.ts +11 -3
- package/dist/pc/pc.pools.js +9 -13
- package/dist/pc/pc.proficiencies.d.ts +54 -29
- package/dist/pc/pc.proficiencies.js +74 -95
- package/dist/pc/pc.proficiency-grants.d.ts +58 -0
- package/dist/pc/pc.proficiency-normalize.d.ts +24 -0
- package/dist/pc/pc.proficiency-normalize.js +12 -0
- package/dist/pc/pc.proficiency-query.d.ts +13 -0
- package/dist/pc/pc.proficiency-query.js +1 -1
- package/dist/pc/pc.recalc.d.ts +69 -14
- package/dist/pc/pc.recalc.js +261 -122
- package/dist/pc/pc.resolver.d.ts +34 -8
- package/dist/pc/pc.resolver.js +27 -12
- package/dist/pc/pc.resource-seed.d.ts +3 -2
- package/dist/pc/pc.resource-seed.js +19 -17
- package/dist/pc/pc.resources.d.ts +87 -0
- package/dist/pc/pc.resources.js +21 -0
- package/dist/pc/pc.rest.d.ts +10 -1
- package/dist/pc/pc.rest.js +66 -12
- package/dist/pc/pc.schema.d.ts +139 -3
- package/dist/pc/pc.schema.js +4 -2
- package/dist/pc/pc.slotting.js +3 -3
- package/dist/pc/pc.spellcasting.d.ts +75 -6
- package/dist/pc/pc.spellcasting.js +16 -6
- package/dist/pc/pc.table-column.d.ts +23 -0
- package/dist/pc/pc.table-column.js +13 -3
- package/dist/pc/pc.types.d.ts +251 -12
- package/dist/pc/pool-layout.d.ts +47 -0
- package/dist/pc/pool-layout.js +16 -0
- package/dist/pc/roll-scope.d.ts +2 -0
- package/dist/pc/roll-scope.js +8 -0
- package/dist/pc/roll-tag-labels.d.ts +40 -0
- package/dist/pc/roll-tag-labels.js +17 -0
- package/dist/pc/spell-source.d.ts +21 -0
- package/dist/pc/spell-source.js +13 -0
- package/dist/race/race.codec.js +9 -7
- package/dist/race/race.parser.js +8 -6
- package/dist/race/race.schema.d.ts +51 -1
- package/dist/race/race.schema.js +8 -5
- package/dist/race/race.structural.d.ts +7 -0
- package/dist/race/race.structural.js +6 -0
- package/dist/race/race.types.d.ts +20 -0
- package/dist/schemas/attack-schema.d.ts +5 -0
- package/dist/schemas/caster-type-schema.d.ts +14 -0
- package/dist/schemas/caster-type-schema.js +6 -0
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/entity-extras-schema.d.ts +53 -0
- package/dist/schemas/entity-extras-schema.js +10 -0
- package/dist/schemas/equipment-grant-schema.d.ts +2 -0
- package/dist/schemas/equipment-grant-schema.js +1 -1
- package/dist/schemas/feature-alias.d.ts +34 -0
- package/dist/schemas/feature-effect-schema.d.ts +133 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.d.ts +8 -0
- package/dist/schemas/feature-schema.js +6 -4
- package/dist/schemas/resource-schema.d.ts +43 -0
- package/dist/schemas/resource-schema.js +1 -1
- package/dist/schemas/selection-pool-schema.d.ts +2 -0
- package/dist/schemas/selection-pool-schema.js +1 -1
- package/dist/spell/spell.access.js +23 -3
- package/dist/spell/spell.codec.js +4 -3
- package/dist/spell/spell.enrichment.js +4 -4
- package/dist/spell/spell.parser.d.ts +30 -0
- package/dist/spell/spell.parser.js +9 -2
- package/dist/spell/spell.scaling.d.ts +27 -6
- package/dist/spell/spell.scaling.js +25 -6
- package/dist/spell/spell.schema.d.ts +44 -2
- package/dist/spell/spell.schema.js +2 -1
- package/dist/spell/spell.types.d.ts +14 -0
- package/dist/subclass/subclass.codec.d.ts +1 -1
- package/dist/subclass/subclass.codec.js +11 -8
- package/dist/subclass/subclass.parser.js +10 -7
- package/dist/subclass/subclass.schema.d.ts +54 -7
- package/dist/subclass/subclass.schema.js +8 -6
- package/dist/subclass/subclass.types.d.ts +20 -2
- package/dist/types/choice.d.ts +53 -2
- package/dist/types/choice.js +13 -1
- package/dist/types/equipment-grant.d.ts +8 -1
- package/dist/types/feature-effect.d.ts +85 -23
- package/dist/types/feature.d.ts +70 -1
- package/dist/types/optional-feature.types.d.ts +28 -0
- package/dist/types/resource.d.ts +21 -1
- package/dist/types/selection-pool.d.ts +17 -2
- package/dist/weapon/weapon.classify.js +2 -2
- package/dist/weapon/weapon.codec.js +4 -3
- package/dist/weapon/weapon.parser.js +3 -2
- package/dist/weapon/weapon.schema.d.ts +4 -0
- package/dist/weapon/weapon.schema.js +2 -1
- package/dist/weapon/weapon.types.d.ts +8 -0
- package/package.json +2 -2
- package/dist/chunk-5XUXXAQJ.js +0 -30
- package/dist/chunk-7P65Q426.js +0 -158
- package/dist/chunk-7TEK5KK7.js +0 -49
- package/dist/chunk-AIRFC5NQ.js +0 -143
- package/dist/chunk-CZPMTQOY.js +0 -68
- package/dist/chunk-N2JE7BWL.js +0 -81
- package/dist/chunk-NXR3BD2V.js +0 -90
- package/dist/chunk-O5EYMKFH.js +0 -6
- package/dist/chunk-Q5K6LWBZ.js +0 -45
- package/dist/chunk-TNUFPIXI.js +0 -1110
- package/dist/chunk-TZK36BU7.js +0 -38
- package/dist/chunk-W7HWMMBF.js +0 -46
- package/dist/chunk-Y4I74YEG.js +0 -33
package/dist/pc/pc.resolver.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { RaceEntity } from "@archivist-gg/dnd5e/race/race.types";
|
|
|
3
3
|
import type { BackgroundEntity } from "@archivist-gg/dnd5e/background/background.types";
|
|
4
4
|
import type { FeatEntity } from "@archivist-gg/dnd5e/feat/feat.types";
|
|
5
5
|
import type { Ability } from "@archivist-gg/dnd5e";
|
|
6
|
-
import type { Character, ChoiceValue, ResolvedCharacter, ResolvedClass, ResolvedFeature, ResolvedSpell } from "./pc.types.js";
|
|
6
|
+
import type { Character, ChoiceValue, ResolvedCharacter, ResolvedClass, ResolvedFeature, ResolvedSpell, FeatVia } from "./pc.types.js";
|
|
7
7
|
export interface ResolveResult {
|
|
8
8
|
character: ResolvedCharacter;
|
|
9
9
|
warnings: string[];
|
|
@@ -19,8 +19,19 @@ export declare function stripSlug(ref: string | null): string | null;
|
|
|
19
19
|
* resolve to the BASE feat ("magic-initiate") while keeping the full variant
|
|
20
20
|
* string as the display name. Returns null when the ref is empty or resolves to no
|
|
21
21
|
* feat (an unresolvable ref folds nothing into the pipeline).
|
|
22
|
+
*
|
|
23
|
+
* R4-G4 §8: this is a SEVEN-TIER cascade, first hit wins, and the granting
|
|
24
|
+
* BACKGROUND's slug arrives as `ownerSlug` so the compendium-scoped tiers can read
|
|
25
|
+
* its prefix. It replaces the old two-tier "exact slug, else FIRST tail match"
|
|
26
|
+
* lookup, whose two defects were measured on the shipped corpora: a tail match on a
|
|
27
|
+
* DIFFERENT real feat pre-empted the parenthetical strip (PHB 2024
|
|
28
|
+
* "Magic Initiate; Cleric", tail `magic-initiate-cleric`, beat SRD 2024
|
|
29
|
+
* "Magic Initiate" for every 2024 Acolyte / Sage, order-independently), and where
|
|
30
|
+
* several same-NAMED feats exist the registry order decided which one won
|
|
31
|
+
* (`EntityRegistry.search` sorts by lowercased name, so equal names fall through to
|
|
32
|
+
* insertion order).
|
|
22
33
|
*/
|
|
23
|
-
export declare function resolveOriginFeat(entities: EntityRegistry, originFeatRef: string | null): {
|
|
34
|
+
export declare function resolveOriginFeat(entities: EntityRegistry, originFeatRef: string | null | undefined, ownerSlug?: string | null): {
|
|
24
35
|
feat: FeatEntity;
|
|
25
36
|
display: string;
|
|
26
37
|
} | null;
|
|
@@ -44,10 +55,17 @@ export declare function collectChosenWeaponMasteries(character: Character): {
|
|
|
44
55
|
full: string[];
|
|
45
56
|
};
|
|
46
57
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
58
|
+
* R4-G7 T8 RIDER-23 · every `choices[<level>].feat` pick with the slot it was taken at: the index of its class entry and
|
|
59
|
+
* the level key as a number (`null` when the key is not an integer). De-duplicated by slug in first-seen order (class
|
|
60
|
+
* entries in order, level keys ascending as `Object.entries` yields integer keys), so a feat picked twice keeps its FIRST
|
|
61
|
+
* slot. Slugs are bare (no `[[ ]]`). The resolver's one walk of class.choices for `feat` entries: the slug-only wrapper that
|
|
62
|
+
* mapped it had no production caller after RIDER-23 and was retired in wave D fix round 1.
|
|
49
63
|
*/
|
|
50
|
-
export declare function
|
|
64
|
+
export declare function collectFeatPicks(character: Character): {
|
|
65
|
+
slug: string;
|
|
66
|
+
classIndex: number;
|
|
67
|
+
level: number | null;
|
|
68
|
+
}[];
|
|
51
69
|
/**
|
|
52
70
|
* Feat→spell application (3d). Walks a feat's OWN `choices` to find its spell
|
|
53
71
|
* picks and turns each into a ResolvedSpell. A feat's spells sit behind a
|
|
@@ -80,8 +98,16 @@ export declare function collectItemGrantedSpells(character: Character, ownAbilit
|
|
|
80
98
|
* Collapses duplicate resolved spells (3d Minor #2 carry-forward + P4-T3 segmented
|
|
81
99
|
* dedupe). A spell can be emitted more than once: it may be BOTH in
|
|
82
100
|
* `character.spells.known` AND a feat pick, or a feat may be taken as both origin +
|
|
83
|
-
* class-slot
|
|
84
|
-
*
|
|
101
|
+
* class-slot, or an `additional_spells` grant (R4-G3b §5) may name a spell the character
|
|
102
|
+
* already knows. A class-sourced copy owns a real DC via its `classSlug`, so it always
|
|
103
|
+
* wins over a feat copy of the same slug; otherwise the FIRST-SEEN copy holds the slot.
|
|
104
|
+
* Which copy holds the slot is not the whole answer, though: `alwaysPrepared` is OR-merged
|
|
105
|
+
* onto the winner in BOTH collision orders (R4-G3b §5.2.8), so a hand-added Bless that a
|
|
106
|
+
* subclass later grants stops counting against the prepared limit instead of counting
|
|
107
|
+
* forever. `persisted` crosses the merge as well, in both orders (fix 1b): removability is
|
|
108
|
+
* MEMBERSHIP in `character.spells.known`, so the flag belongs to the SLUG, not to whichever
|
|
109
|
+
* copy won. Nothing else crosses: the winner keeps its own `source` / `classSlug` /
|
|
110
|
+
* `entryIndex`. Insertion order
|
|
85
111
|
* is preserved (a later class copy replaces an earlier feat copy in place), so the
|
|
86
112
|
* Spells section never renders duplicate rows while a legitimately class-known copy is
|
|
87
113
|
* never lost. Item-source spells carry INSTANCE identity: they key by
|
|
@@ -101,4 +127,4 @@ export declare function collectChosenGrantedFeatures(character: Character, class
|
|
|
101
127
|
data: Record<string, unknown>;
|
|
102
128
|
} | undefined;
|
|
103
129
|
}, race?: RaceEntity | null, background?: BackgroundEntity | null): ResolvedFeature[];
|
|
104
|
-
export declare function collectResolvedFeatures(race: RaceEntity | null, classes: ResolvedClass[], background: BackgroundEntity | null, feats: FeatEntity[]): ResolvedFeature[];
|
|
130
|
+
export declare function collectResolvedFeatures(race: RaceEntity | null, classes: ResolvedClass[], background: BackgroundEntity | null, feats: FeatEntity[], featVia?: ReadonlyMap<string, FeatVia>): ResolvedFeature[];
|
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -3,29 +3,44 @@ import {
|
|
|
3
3
|
collectChosenGrantedFeatures,
|
|
4
4
|
collectChosenWeaponMasteries,
|
|
5
5
|
collectFeatGrantedSpells,
|
|
6
|
-
|
|
6
|
+
collectFeatPicks,
|
|
7
7
|
collectItemGrantedSpells,
|
|
8
8
|
collectResolvedFeatures,
|
|
9
9
|
dedupeResolvedSpells,
|
|
10
10
|
resolveOriginFeat,
|
|
11
11
|
stripSlug
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-2VDTW7QO.js";
|
|
13
|
+
import "../chunk-UXPGW4TI.js";
|
|
14
|
+
import "../chunk-DPUJDOKV.js";
|
|
15
|
+
import "../chunk-O4SRD3J5.js";
|
|
16
|
+
import "../chunk-PP2UHLBA.js";
|
|
17
|
+
import "../chunk-IUAAXXNO.js";
|
|
18
|
+
import "../chunk-YHYTW5QA.js";
|
|
19
|
+
import "../chunk-MI7P3NX3.js";
|
|
20
|
+
import "../chunk-PVCEA4HZ.js";
|
|
21
|
+
import "../chunk-UBBKSYBY.js";
|
|
22
|
+
import "../chunk-KPEJMNRD.js";
|
|
23
|
+
import "../chunk-TOM66P2P.js";
|
|
24
|
+
import "../chunk-KU3YLF6D.js";
|
|
25
|
+
import "../chunk-RLGQ5PZZ.js";
|
|
26
|
+
import "../chunk-LVQLWRCU.js";
|
|
27
|
+
import "../chunk-WXWPK3LI.js";
|
|
28
|
+
import "../chunk-6X4KUDMU.js";
|
|
29
|
+
import "../chunk-YBLDE5CG.js";
|
|
30
|
+
import "../chunk-EVMUJYUD.js";
|
|
20
31
|
import "../chunk-VTTA2ALZ.js";
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
32
|
+
import "../chunk-OZP6JFGT.js";
|
|
33
|
+
import "../chunk-VQAXTIBW.js";
|
|
34
|
+
import "../chunk-PDJSUH24.js";
|
|
35
|
+
import "../chunk-WELIKLZF.js";
|
|
36
|
+
import "../chunk-4U55VNC7.js";
|
|
37
|
+
import "../chunk-UA5KS2PL.js";
|
|
23
38
|
export {
|
|
24
39
|
PCResolver,
|
|
25
40
|
collectChosenGrantedFeatures,
|
|
26
41
|
collectChosenWeaponMasteries,
|
|
27
42
|
collectFeatGrantedSpells,
|
|
28
|
-
|
|
43
|
+
collectFeatPicks,
|
|
29
44
|
collectItemGrantedSpells,
|
|
30
45
|
collectResolvedFeatures,
|
|
31
46
|
dedupeResolvedSpells,
|
|
@@ -4,7 +4,8 @@ import type { FormulaBindings } from "@archivist-gg/dnd5e/dnd/resource-formula";
|
|
|
4
4
|
* is the character's level in the granting class; for a `subclass` source it
|
|
5
5
|
* is the level in the class that OWNS that subclass, and it falls back to the
|
|
6
6
|
* total level for race/background/feat sources (or when the class isn't found).
|
|
7
|
-
* Also binds `columns`
|
|
7
|
+
* Also binds `columns` · the numeric values of that (sub)class's table row at
|
|
8
8
|
* `class_level` (empty when there is no table/row), backing the `column('Name')`
|
|
9
|
-
* accessor in the DSL. Ability mods come from the final (post-bonus) derived mods.
|
|
9
|
+
* accessor in the DSL. Ability mods come from the final (post-bonus) derived mods.
|
|
10
|
+
* `class_level` comes from `resourceLevelFor` (pc.resources.ts), the one derivation. */
|
|
10
11
|
export declare function resourceBindings(resolved: ResolvedCharacter, derived: DerivedStats, source: FeatureSource): FormulaBindings;
|
|
@@ -1,27 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resourceLevelFor
|
|
3
|
+
} from "../chunk-UXPGW4TI.js";
|
|
4
|
+
import "../chunk-DPUJDOKV.js";
|
|
1
5
|
import {
|
|
2
6
|
numericColumnsAt
|
|
3
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-IUAAXXNO.js";
|
|
8
|
+
import "../chunk-LVQLWRCU.js";
|
|
9
|
+
import "../chunk-EVMUJYUD.js";
|
|
10
|
+
import "../chunk-VTTA2ALZ.js";
|
|
11
|
+
import "../chunk-PDJSUH24.js";
|
|
12
|
+
import "../chunk-WELIKLZF.js";
|
|
4
13
|
|
|
5
14
|
// src/pc/pc.resource-seed.ts
|
|
6
15
|
function resourceBindings(resolved, derived, source) {
|
|
7
16
|
var _a, _b, _c, _d;
|
|
8
|
-
|
|
17
|
+
const classLevel = resourceLevelFor(source, resolved);
|
|
9
18
|
let table;
|
|
10
|
-
if (source.kind === "class") {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
const c = resolved.classes.find((c2) => {
|
|
19
|
-
var _a2;
|
|
20
|
-
return ((_a2 = c2.subclass) == null ? void 0 : _a2.slug) === source.slug;
|
|
21
|
-
});
|
|
22
|
-
classLevel = (_c = c == null ? void 0 : c.level) != null ? _c : resolved.totalLevel;
|
|
23
|
-
table = (_d = c == null ? void 0 : c.subclass) == null ? void 0 : _d.table;
|
|
24
|
-
}
|
|
19
|
+
if (source.kind === "class") table = (_b = (_a = resolved.classes.find((c) => {
|
|
20
|
+
var _a2;
|
|
21
|
+
return ((_a2 = c.entity) == null ? void 0 : _a2.slug) === source.slug;
|
|
22
|
+
})) == null ? void 0 : _a.entity) == null ? void 0 : _b.table;
|
|
23
|
+
else if (source.kind === "subclass") table = (_d = (_c = resolved.classes.find((c) => {
|
|
24
|
+
var _a2;
|
|
25
|
+
return ((_a2 = c.subclass) == null ? void 0 : _a2.slug) === source.slug;
|
|
26
|
+
})) == null ? void 0 : _c.subclass) == null ? void 0 : _d.table;
|
|
25
27
|
return {
|
|
26
28
|
level: resolved.totalLevel,
|
|
27
29
|
class_level: classLevel,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { FeatureSource, ResolvedCharacter, ResolvedFeature, ResolvedPool, DerivedStats } from "./pc.types.js";
|
|
2
|
+
import type { ResourceRecovery, ResourceDie, ResourceScaleStep, ResetTrigger } from "../types/resource.js";
|
|
3
|
+
/** The level a resource granted via `source` scales against (R4-G4 §6.2.4, ONE derivation): the
|
|
4
|
+
* character's level in the granting class; for a `subclass` source the level in the class that OWNS
|
|
5
|
+
* that subclass; the total level for race / background / feat sources, or when the class is not found.
|
|
6
|
+
* `resourceBindings` (pc.resource-seed.ts) binds `class_level` through this function, and R4-G4 T3
|
|
7
|
+
* (§6.2.4 / §6.2.5) routed the plugin's three former TOTAL-level reads through it too, so
|
|
8
|
+
* `class_level`, `scales_at` and the die can no longer disagree. T4 added a fourth read, the die label
|
|
9
|
+
* of `renderSpendControl`, and T5 a fifth, the die label of the pool tab's dice head.
|
|
10
|
+
*
|
|
11
|
+
* The units, re-measured 2026-09-06 on the SHIPPED plugin tree with
|
|
12
|
+
* `grep -rn "resourceLevelFor(" packages/obsidian/src`, which returns FOUR lines: FIVE READS reach
|
|
13
|
+
* this function through FOUR call EXPRESSIONS living in FOUR functions across FOUR files. The
|
|
14
|
+
* expressions are the plugin SEED (`seedFeatureUses` in `pc.resource-seed.ts`, for the level it hands
|
|
15
|
+
* `resolveMaxCountAt`), the module-private `resourceLevel(id, ctx)` helper of
|
|
16
|
+
* `components/actions/feature-rows.ts` (which resolves the owner from `resolved.resources` and falls
|
|
17
|
+
* back to the total level when there is none), `renderSpendControl`
|
|
18
|
+
* (`components/actions/spend-control.ts`) and `renderPoolHead` (`components/pool-tab.ts`). The count
|
|
19
|
+
* of READS is one higher than the count of expressions because `resourceLevel` serves TWO
|
|
20
|
+
* `resolveScalingDie` die labels, one in `renderCardResource` and one in `formatFeatureAttackNote`:
|
|
21
|
+
* so THREE of the five reads call this function directly (the seed, the spend control, the pool head)
|
|
22
|
+
* and TWO reach it through `resourceLevel`. Each render-time reader passes the owner its index entry
|
|
23
|
+
* already carries, so a die label and the tracker beside it read the same level. So a
|
|
24
|
+
* Barbarian 5 / Fighter 5 reads the level-5 Rage count, not the level-10 one. */
|
|
25
|
+
export declare function resourceLevelFor(source: FeatureSource, resolved: ResolvedCharacter): number;
|
|
26
|
+
export type ResourceOwner = {
|
|
27
|
+
kind: "feature";
|
|
28
|
+
featureId: string;
|
|
29
|
+
featureName: string;
|
|
30
|
+
source: FeatureSource;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "pool";
|
|
33
|
+
poolId: string;
|
|
34
|
+
poolLabel: string;
|
|
35
|
+
source: FeatureSource;
|
|
36
|
+
};
|
|
37
|
+
export type RecoveryKind = "uses" | "spell-slots";
|
|
38
|
+
export type RecoveryFlavour = "rest" | "manual";
|
|
39
|
+
export interface ResolvedRecovery {
|
|
40
|
+
entry: ResourceRecovery;
|
|
41
|
+
kind: RecoveryKind;
|
|
42
|
+
flavour: RecoveryFlavour;
|
|
43
|
+
}
|
|
44
|
+
export interface ResolvedResource {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
reset: ResetTrigger;
|
|
48
|
+
maxFormula: string;
|
|
49
|
+
die?: ResourceDie;
|
|
50
|
+
scalesAt?: ResourceScaleStep[];
|
|
51
|
+
recovery?: ResolvedRecovery[];
|
|
52
|
+
owner: ResourceOwner;
|
|
53
|
+
}
|
|
54
|
+
export type ResourceIndex = ReadonlyMap<string, ResolvedResource>;
|
|
55
|
+
/** KIND first (the schema key; absent = `uses`, UR2), FLAVOUR second (`action` / `reset`): a
|
|
56
|
+
* `spell-slots` entry is ALWAYS manual (the slot picker), whatever its action / reset say; a `uses`
|
|
57
|
+
* entry is a rest restore when its `reset` is `short-rest` or `long-rest` AND it carries no `action`,
|
|
58
|
+
* else manual (R4-G4 §7.2, invariant 12). The other rest-shaped triggers (`either`, `dawn`, `dusk`)
|
|
59
|
+
* read manual here: §7.1's partition of the 33 shipped entries has no carrier among them, and §15
|
|
60
|
+
* keeps the reset VOCABULARY of the rest arm deferred to G8.
|
|
61
|
+
*
|
|
62
|
+
* BOTH arms it routes are LANDED as of R4-G4 T7, and its CALLERS are counted here rather than its
|
|
63
|
+
* grep hits, because a docblock that names the function moves its own grep count. Measured
|
|
64
|
+
* 2026-09-05 on both trees: dnd5e has exactly ONE caller, `toResolvedResource` below, which STAMPS
|
|
65
|
+
* the kind and the flavour onto every entry of every indexed resource, so `pushPartialRecoveries`
|
|
66
|
+
* (pc.rest.ts) reads that stamp to emit the rest arm's partial category and never calls this
|
|
67
|
+
* function itself; the plugin has exactly ONE, `renderRecoveryAction` (blocks/feature-card.ts),
|
|
68
|
+
* which calls it directly and picks the card's arm from the KIND, then the FLAVOUR
|
|
69
|
+
* (`grep -rn "resolveRecovery" packages/obsidian/src` returns THREE lines there: the import, that
|
|
70
|
+
* call and one docblock mention). */
|
|
71
|
+
export declare function resolveRecovery(entry: ResourceRecovery): ResolvedRecovery;
|
|
72
|
+
/** ONE walk over `features[].feature.resources` (the walk `findResourceById` used to do per call). The
|
|
73
|
+
* owner is the DECLARING feature; a duplicate id keeps the FIRST declaration (seeding keeps its own
|
|
74
|
+
* max-of-maxes merge). Reads the features array ONLY. `name` falls back to the owning feature's name,
|
|
75
|
+
* the rule `findResourceById` carried, for resources synthesised from older fixtures that omit it. */
|
|
76
|
+
export declare function resolveFeatureResources(features: ReadonlyArray<ResolvedFeature>): ResourceIndex;
|
|
77
|
+
/** The full index: the feature resources (`resolveFeatureResources`) plus the pool picks' own
|
|
78
|
+
* `uses` (R4-G4 §12, LANDED at T7b). A pure function of `resolved.features` and `resolved.pools`,
|
|
79
|
+
* each guarded `?? []` because the cast fixtures behind the rest suites in both repos carry
|
|
80
|
+
* neither; `computeRestPlan` derives it per call and never reads `resolved.resources`, the
|
|
81
|
+
* resolver stores it on `resolved.resources` after pools resolve, and the resolver suite pins the
|
|
82
|
+
* stored index equal to a fresh derivation. */
|
|
83
|
+
export declare function resolveResourceIndex(resolved: ResolvedCharacter): ResourceIndex;
|
|
84
|
+
/** 8 + prof + mod(ability) when the pool's owning class's subclass carries `spellcasting.ability` AND
|
|
85
|
+
* `resolveSpellcasting` returns null for that class (no caster profile: the Four Elements shape); null
|
|
86
|
+
* otherwise. Reads `subclass.spellcasting.ability` and NEVER `dc_formula` (R4-G4 §11.2). */
|
|
87
|
+
export declare function poolSaveDC(resolved: ResolvedCharacter, derived: DerivedStats, pool: ResolvedPool): number | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
poolSaveDC,
|
|
3
|
+
resolveFeatureResources,
|
|
4
|
+
resolveRecovery,
|
|
5
|
+
resolveResourceIndex,
|
|
6
|
+
resourceLevelFor
|
|
7
|
+
} from "../chunk-UXPGW4TI.js";
|
|
8
|
+
import "../chunk-DPUJDOKV.js";
|
|
9
|
+
import "../chunk-IUAAXXNO.js";
|
|
10
|
+
import "../chunk-LVQLWRCU.js";
|
|
11
|
+
import "../chunk-EVMUJYUD.js";
|
|
12
|
+
import "../chunk-VTTA2ALZ.js";
|
|
13
|
+
import "../chunk-PDJSUH24.js";
|
|
14
|
+
import "../chunk-WELIKLZF.js";
|
|
15
|
+
export {
|
|
16
|
+
poolSaveDC,
|
|
17
|
+
resolveFeatureResources,
|
|
18
|
+
resolveRecovery,
|
|
19
|
+
resolveResourceIndex,
|
|
20
|
+
resourceLevelFor
|
|
21
|
+
};
|
package/dist/pc/pc.rest.d.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import type { EntityRegistry } from "@archivist-gg/core";
|
|
2
2
|
import type { Character, DerivedStats, ResolvedCharacter } from "./pc.types.js";
|
|
3
3
|
export type RestType = "short" | "long";
|
|
4
|
-
export type RestCategoryId = "hp-to-max" | "hd-regain" | "spell-slots" | "pact-slots" | "exhaustion" | "hp-modifier-reset" | `feature:${string}` | `item:${number}
|
|
4
|
+
export type RestCategoryId = "hp-to-max" | "hd-regain" | "spell-slots" | "pact-slots" | "exhaustion" | "hp-modifier-reset" | `feature:${string}` | `item:${number}`
|
|
5
|
+
/** R4-G5 §4.4.2: END an active buff whose carrier declares a structured `duration`. The tail is the STORED
|
|
6
|
+
* `state.active_buffs` key (a class feature's `id` or a pool entry's resolved `slug`). Emitted by
|
|
7
|
+
* `pushBuffEnds` below and read by the plugin's `applyRestResets`, whose `buff:` arm removes that key
|
|
8
|
+
* from `state.active_buffs`. That arm is the plugin half of R4-G5 Task 6: this type is the task's
|
|
9
|
+
* dnd5e hard edge and is committed first. */
|
|
10
|
+
| `buff:${string}`;
|
|
5
11
|
export interface RestCategory {
|
|
6
12
|
id: RestCategoryId;
|
|
7
13
|
label: string;
|
|
8
14
|
preview: string;
|
|
15
|
+
/** R4-G4 §7.2.2: a PARTIAL restore from a `recovery[]` entry of kind `uses` and flavour `rest` (N uses, or "all"),
|
|
16
|
+
* emitted only when the resource's own `reset` does not already fire at this rest. Absent = the own reset (to 0). */
|
|
17
|
+
restore?: number | "all";
|
|
9
18
|
}
|
|
10
19
|
export interface RestPlan {
|
|
11
20
|
type: RestType;
|
package/dist/pc/pc.rest.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveResourceIndex
|
|
3
|
+
} from "../chunk-UXPGW4TI.js";
|
|
4
|
+
import "../chunk-DPUJDOKV.js";
|
|
5
|
+
import "../chunk-IUAAXXNO.js";
|
|
6
|
+
import "../chunk-LVQLWRCU.js";
|
|
7
|
+
import "../chunk-EVMUJYUD.js";
|
|
8
|
+
import "../chunk-VTTA2ALZ.js";
|
|
9
|
+
import "../chunk-PDJSUH24.js";
|
|
10
|
+
import "../chunk-WELIKLZF.js";
|
|
11
|
+
|
|
1
12
|
// src/pc/pc.rest.ts
|
|
2
13
|
function resolveItemName(entry, registry) {
|
|
3
14
|
var _a;
|
|
@@ -6,19 +17,58 @@ function resolveItemName(entry, registry) {
|
|
|
6
17
|
const slug = ref ? ref[1] : entry.item;
|
|
7
18
|
return (_a = registry.getBySlug(slug)) == null ? void 0 : _a.name;
|
|
8
19
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
var FIRES_AT = {
|
|
21
|
+
long: /* @__PURE__ */ new Set(["short-rest", "long-rest", "either", "dawn", "dusk"]),
|
|
22
|
+
short: /* @__PURE__ */ new Set(["short-rest", "either"])
|
|
23
|
+
};
|
|
24
|
+
function pushPartialRecoveries(cats, character, index, type) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
for (const [key, fu] of Object.entries((_a = character.state.feature_uses) != null ? _a : {})) {
|
|
27
|
+
if (fu.used <= 0) continue;
|
|
28
|
+
const res = index.get(key);
|
|
29
|
+
if (!((_b = res == null ? void 0 : res.recovery) == null ? void 0 : _b.length)) continue;
|
|
30
|
+
if (FIRES_AT[type].has(res.reset)) continue;
|
|
31
|
+
const entry = res.recovery.find((r) => r.kind === "uses" && r.flavour === "rest" && FIRES_AT[type].has(r.entry.reset));
|
|
32
|
+
if (!entry) continue;
|
|
33
|
+
const amount = entry.entry.amount;
|
|
34
|
+
const restore = amount === "all" ? "all" : typeof amount === "number" ? amount : Number(amount);
|
|
35
|
+
if (restore !== "all" && !Number.isFinite(restore)) continue;
|
|
36
|
+
const n = restore === "all" ? fu.used : Math.min(fu.used, restore);
|
|
37
|
+
cats.push({ id: `feature:${key}`, label: res.name, preview: `${n} of ${fu.used} used restored`, restore });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function pushBuffEnds(cats, character, resolved) {
|
|
41
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
42
|
+
const structured = (d) => !!d && typeof d === "object";
|
|
43
|
+
for (const key of (_a = character.state.active_buffs) != null ? _a : []) {
|
|
44
|
+
let found = false;
|
|
45
|
+
let name = key;
|
|
46
|
+
for (const rf of (_b = resolved.features) != null ? _b : []) {
|
|
47
|
+
if (rf.feature.id === key && structured(rf.feature.duration)) {
|
|
48
|
+
found = true;
|
|
49
|
+
name = (_c = rf.feature.name) != null ? _c : key;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!found) {
|
|
54
|
+
for (const pool of (_d = resolved.pools) != null ? _d : []) {
|
|
55
|
+
const entry = [...(_e = pool.selected) != null ? _e : [], ...(_f = pool.grants) != null ? _f : []].find((e) => e.slug === key);
|
|
56
|
+
if (entry && structured(entry.entity.duration)) {
|
|
57
|
+
found = true;
|
|
58
|
+
name = (_g = entry.entity.name) != null ? _g : key;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
14
62
|
}
|
|
63
|
+
if (!found) continue;
|
|
64
|
+
cats.push({ id: `buff:${key}`, label: `End ${name}`, preview: "active \u2192 ended" });
|
|
15
65
|
}
|
|
16
|
-
return void 0;
|
|
17
66
|
}
|
|
18
67
|
function computeRestPlan(character, resolved, derived, registry, type) {
|
|
19
68
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
20
69
|
const cats = [];
|
|
21
70
|
let hdRegainDist;
|
|
71
|
+
const index = resolveResourceIndex(resolved);
|
|
22
72
|
const pact = character.state.spell_slots_pact;
|
|
23
73
|
if (pact && pact.used > 0) {
|
|
24
74
|
cats.push({ id: "pact-slots", label: "Pact Magic Slots", preview: "all reset" });
|
|
@@ -79,15 +129,16 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
79
129
|
}
|
|
80
130
|
for (const [key, fu] of Object.entries((_f = character.state.feature_uses) != null ? _f : {})) {
|
|
81
131
|
if (fu.used <= 0) continue;
|
|
82
|
-
const res =
|
|
132
|
+
const res = index.get(key);
|
|
83
133
|
const reset = (_g = res == null ? void 0 : res.reset) != null ? _g : "long-rest";
|
|
84
|
-
if (reset !== "short-rest" && reset !== "long-rest" && reset !== "dawn" && reset !== "dusk") continue;
|
|
134
|
+
if (reset !== "short-rest" && reset !== "long-rest" && reset !== "either" && reset !== "dawn" && reset !== "dusk") continue;
|
|
85
135
|
cats.push({
|
|
86
136
|
id: `feature:${key}`,
|
|
87
|
-
label: (_h = res == null ? void 0 : res.
|
|
137
|
+
label: (_h = res == null ? void 0 : res.name) != null ? _h : key,
|
|
88
138
|
preview: `${fu.used}/${fu.max} restored`
|
|
89
139
|
});
|
|
90
140
|
}
|
|
141
|
+
pushPartialRecoveries(cats, character, index, "long");
|
|
91
142
|
character.equipment.forEach((entry, idx) => {
|
|
92
143
|
var _a2, _b2, _c2, _d2, _e2;
|
|
93
144
|
const rec = (_a2 = entry.state) == null ? void 0 : _a2.recovery;
|
|
@@ -106,14 +157,16 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
106
157
|
if (type === "short") {
|
|
107
158
|
for (const [key, fu] of Object.entries((_i = character.state.feature_uses) != null ? _i : {})) {
|
|
108
159
|
if (fu.used <= 0) continue;
|
|
109
|
-
const res =
|
|
110
|
-
|
|
160
|
+
const res = index.get(key);
|
|
161
|
+
const r = (_j = res == null ? void 0 : res.reset) != null ? _j : "long-rest";
|
|
162
|
+
if (r !== "short-rest" && r !== "either") continue;
|
|
111
163
|
cats.push({
|
|
112
164
|
id: `feature:${key}`,
|
|
113
|
-
label: (_k = res == null ? void 0 : res.
|
|
165
|
+
label: (_k = res == null ? void 0 : res.name) != null ? _k : key,
|
|
114
166
|
preview: `${fu.used}/${fu.max} restored`
|
|
115
167
|
});
|
|
116
168
|
}
|
|
169
|
+
pushPartialRecoveries(cats, character, index, "short");
|
|
117
170
|
character.equipment.forEach((entry, idx) => {
|
|
118
171
|
var _a2, _b2, _c2, _d2, _e2;
|
|
119
172
|
const rec = (_a2 = entry.state) == null ? void 0 : _a2.recovery;
|
|
@@ -129,6 +182,7 @@ function computeRestPlan(character, resolved, derived, registry, type) {
|
|
|
129
182
|
});
|
|
130
183
|
});
|
|
131
184
|
}
|
|
185
|
+
pushBuffEnds(cats, character, resolved);
|
|
132
186
|
const hdAvailable = type === "short" ? Object.entries((_l = character.state.hit_dice) != null ? _l : {}).filter(([, hd]) => hd.used < hd.total).map(([die, hd]) => ({ die, remaining: hd.total - hd.used })) : [];
|
|
133
187
|
return { type, categories: cats, hdAvailable, hdRegainDist };
|
|
134
188
|
}
|
package/dist/pc/pc.schema.d.ts
CHANGED
|
@@ -1,4 +1,113 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare const characterOverridesShape: z.ZodObject<{
|
|
3
|
+
scores: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
4
|
+
str: "str";
|
|
5
|
+
dex: "dex";
|
|
6
|
+
con: "con";
|
|
7
|
+
int: "int";
|
|
8
|
+
wis: "wis";
|
|
9
|
+
cha: "cha";
|
|
10
|
+
}> & z.core.$partial, z.ZodNumber>>;
|
|
11
|
+
saves: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
12
|
+
str: "str";
|
|
13
|
+
dex: "dex";
|
|
14
|
+
con: "con";
|
|
15
|
+
int: "int";
|
|
16
|
+
wis: "wis";
|
|
17
|
+
cha: "cha";
|
|
18
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
19
|
+
bonus: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
proficient: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
}, z.core.$strip>>>;
|
|
22
|
+
skills: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
23
|
+
acrobatics: "acrobatics";
|
|
24
|
+
"animal-handling": "animal-handling";
|
|
25
|
+
arcana: "arcana";
|
|
26
|
+
athletics: "athletics";
|
|
27
|
+
deception: "deception";
|
|
28
|
+
history: "history";
|
|
29
|
+
insight: "insight";
|
|
30
|
+
intimidation: "intimidation";
|
|
31
|
+
investigation: "investigation";
|
|
32
|
+
medicine: "medicine";
|
|
33
|
+
nature: "nature";
|
|
34
|
+
perception: "perception";
|
|
35
|
+
performance: "performance";
|
|
36
|
+
persuasion: "persuasion";
|
|
37
|
+
religion: "religion";
|
|
38
|
+
"sleight-of-hand": "sleight-of-hand";
|
|
39
|
+
stealth: "stealth";
|
|
40
|
+
survival: "survival";
|
|
41
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
42
|
+
bonus: z.ZodNumber;
|
|
43
|
+
proficiency: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
none: "none";
|
|
45
|
+
expertise: "expertise";
|
|
46
|
+
proficient: "proficient";
|
|
47
|
+
}>>;
|
|
48
|
+
}, z.core.$strip>>>;
|
|
49
|
+
passives: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
perception: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
51
|
+
investigation: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
52
|
+
insight: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
53
|
+
}, z.core.$strip>>;
|
|
54
|
+
hp: z.ZodOptional<z.ZodObject<{
|
|
55
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
rolled: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
modifier: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
ac: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
speed: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
initiative: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
spellcasting_ability_by_class: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
63
|
+
str: "str";
|
|
64
|
+
dex: "dex";
|
|
65
|
+
con: "con";
|
|
66
|
+
int: "int";
|
|
67
|
+
wis: "wis";
|
|
68
|
+
cha: "cha";
|
|
69
|
+
}>>>;
|
|
70
|
+
spellcasting_ability: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
str: "str";
|
|
72
|
+
dex: "dex";
|
|
73
|
+
con: "con";
|
|
74
|
+
int: "int";
|
|
75
|
+
wis: "wis";
|
|
76
|
+
cha: "cha";
|
|
77
|
+
}>>;
|
|
78
|
+
spell_slots: z.ZodOptional<z.ZodRecord<z.ZodCoercedNumber<unknown>, z.ZodNumber>>;
|
|
79
|
+
attunement_limit: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
languages: z.ZodOptional<z.ZodObject<{
|
|
81
|
+
add: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
82
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
83
|
+
}, z.core.$strip>>;
|
|
84
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
85
|
+
add: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
86
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
87
|
+
proficiency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
88
|
+
none: "none";
|
|
89
|
+
expertise: "expertise";
|
|
90
|
+
proficient: "proficient";
|
|
91
|
+
}>>>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
defenses: z.ZodOptional<z.ZodObject<{
|
|
94
|
+
resistances: z.ZodOptional<z.ZodObject<{
|
|
95
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
96
|
+
}, z.core.$strip>>;
|
|
97
|
+
immunities: z.ZodOptional<z.ZodObject<{
|
|
98
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
99
|
+
}, z.core.$strip>>;
|
|
100
|
+
vulnerabilities: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
102
|
+
}, z.core.$strip>>;
|
|
103
|
+
condition_immunities: z.ZodOptional<z.ZodObject<{
|
|
104
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
106
|
+
}, z.core.$strip>>;
|
|
107
|
+
}, z.core.$strip>;
|
|
108
|
+
/** The overrides key set as a type. Paired with `keyof CharacterOverrides` by the compile-time parity
|
|
109
|
+
* assertion in pc.types.ts, which is what actually stops a one-sided addition. */
|
|
110
|
+
export type CharacterOverridesSchemaKeys = keyof z.infer<typeof characterOverridesShape>;
|
|
2
111
|
export declare const characterSchema: z.ZodObject<{
|
|
3
112
|
name: z.ZodString;
|
|
4
113
|
edition: z.ZodEnum<{
|
|
@@ -27,10 +136,10 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
27
136
|
cha: z.ZodNumber;
|
|
28
137
|
}, z.core.$strip>;
|
|
29
138
|
ability_method: z.ZodEnum<{
|
|
139
|
+
rolled: "rolled";
|
|
30
140
|
"standard-array": "standard-array";
|
|
31
141
|
"point-buy": "point-buy";
|
|
32
142
|
"archivist-point-buy": "archivist-point-buy";
|
|
33
|
-
rolled: "rolled";
|
|
34
143
|
manual: "manual";
|
|
35
144
|
}>;
|
|
36
145
|
builder_rolls: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
@@ -87,8 +196,8 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
87
196
|
class: z.ZodOptional<z.ZodString>;
|
|
88
197
|
source: z.ZodOptional<z.ZodEnum<{
|
|
89
198
|
domain: "domain";
|
|
90
|
-
race: "race";
|
|
91
199
|
item: "item";
|
|
200
|
+
race: "race";
|
|
92
201
|
class: "class";
|
|
93
202
|
feat: "feat";
|
|
94
203
|
}>>;
|
|
@@ -210,8 +319,8 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
210
319
|
bonus: z.ZodNumber;
|
|
211
320
|
proficiency: z.ZodOptional<z.ZodEnum<{
|
|
212
321
|
none: "none";
|
|
213
|
-
proficient: "proficient";
|
|
214
322
|
expertise: "expertise";
|
|
323
|
+
proficient: "proficient";
|
|
215
324
|
}>>;
|
|
216
325
|
}, z.core.$strip>>>;
|
|
217
326
|
passives: z.ZodOptional<z.ZodObject<{
|
|
@@ -245,6 +354,33 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
245
354
|
}>>;
|
|
246
355
|
spell_slots: z.ZodOptional<z.ZodRecord<z.ZodCoercedNumber<unknown>, z.ZodNumber>>;
|
|
247
356
|
attunement_limit: z.ZodOptional<z.ZodNumber>;
|
|
357
|
+
languages: z.ZodOptional<z.ZodObject<{
|
|
358
|
+
add: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
359
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
360
|
+
}, z.core.$strip>>;
|
|
361
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
362
|
+
add: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
363
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
364
|
+
proficiency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
365
|
+
none: "none";
|
|
366
|
+
expertise: "expertise";
|
|
367
|
+
proficient: "proficient";
|
|
368
|
+
}>>>;
|
|
369
|
+
}, z.core.$strip>>;
|
|
370
|
+
defenses: z.ZodOptional<z.ZodObject<{
|
|
371
|
+
resistances: z.ZodOptional<z.ZodObject<{
|
|
372
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
373
|
+
}, z.core.$strip>>;
|
|
374
|
+
immunities: z.ZodOptional<z.ZodObject<{
|
|
375
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
376
|
+
}, z.core.$strip>>;
|
|
377
|
+
vulnerabilities: z.ZodOptional<z.ZodObject<{
|
|
378
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
379
|
+
}, z.core.$strip>>;
|
|
380
|
+
condition_immunities: z.ZodOptional<z.ZodObject<{
|
|
381
|
+
remove: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
382
|
+
}, z.core.$strip>>;
|
|
383
|
+
}, z.core.$strip>>;
|
|
248
384
|
}, z.core.$strip>>;
|
|
249
385
|
currency: z.ZodOptional<z.ZodObject<{
|
|
250
386
|
cp: z.ZodNumber;
|
package/dist/pc/pc.schema.js
CHANGED