@iamjameslennon/ddb-mcp 2.7.1 → 2.9.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/README.md +2 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -4
- package/dist/browser.js.map +1 -1
- package/dist/index.js +58 -38
- package/dist/index.js.map +1 -1
- package/dist/open5e.d.ts +2 -0
- package/dist/open5e.d.ts.map +1 -1
- package/dist/open5e.js +4 -0
- package/dist/open5e.js.map +1 -1
- package/dist/tools/campaign.js +1 -1
- package/dist/tools/campaign.js.map +1 -1
- package/dist/tools/character/ac.d.ts +20 -0
- package/dist/tools/character/ac.d.ts.map +1 -0
- package/dist/tools/character/ac.js +83 -0
- package/dist/tools/character/ac.js.map +1 -0
- package/dist/tools/character/actions.d.ts +22 -0
- package/dist/tools/character/actions.d.ts.map +1 -0
- package/dist/tools/character/actions.js +110 -0
- package/dist/tools/character/actions.js.map +1 -0
- package/dist/tools/character/core.d.ts +15 -0
- package/dist/tools/character/core.d.ts.map +1 -0
- package/dist/tools/character/core.js +129 -0
- package/dist/tools/character/core.js.map +1 -0
- package/dist/tools/character/defenses.d.ts +16 -0
- package/dist/tools/character/defenses.d.ts.map +1 -0
- package/dist/tools/character/defenses.js +27 -0
- package/dist/tools/character/defenses.js.map +1 -0
- package/dist/tools/character/definition.d.ts +14 -0
- package/dist/tools/character/definition.d.ts.map +1 -0
- package/dist/tools/character/definition.js +205 -0
- package/dist/tools/character/definition.js.map +1 -0
- package/dist/tools/character/features.d.ts +26 -0
- package/dist/tools/character/features.d.ts.map +1 -0
- package/dist/tools/character/features.js +107 -0
- package/dist/tools/character/features.js.map +1 -0
- package/dist/tools/character/helpers.d.ts +57 -0
- package/dist/tools/character/helpers.d.ts.map +1 -0
- package/dist/tools/character/helpers.js +80 -0
- package/dist/tools/character/helpers.js.map +1 -0
- package/dist/tools/character/identity.d.ts +19 -0
- package/dist/tools/character/identity.d.ts.map +1 -0
- package/dist/tools/character/identity.js +84 -0
- package/dist/tools/character/identity.js.map +1 -0
- package/dist/tools/character/inventory.d.ts +21 -0
- package/dist/tools/character/inventory.d.ts.map +1 -0
- package/dist/tools/character/inventory.js +61 -0
- package/dist/tools/character/inventory.js.map +1 -0
- package/dist/tools/character/notes.d.ts +20 -0
- package/dist/tools/character/notes.d.ts.map +1 -0
- package/dist/tools/character/notes.js +63 -0
- package/dist/tools/character/notes.js.map +1 -0
- package/dist/tools/character/parse.d.ts +13 -0
- package/dist/tools/character/parse.d.ts.map +1 -0
- package/dist/tools/character/parse.js +82 -0
- package/dist/tools/character/parse.js.map +1 -0
- package/dist/tools/character/spells.d.ts +26 -0
- package/dist/tools/character/spells.d.ts.map +1 -0
- package/dist/tools/character/spells.js +237 -0
- package/dist/tools/character/spells.js.map +1 -0
- package/dist/tools/character/stats.d.ts +33 -0
- package/dist/tools/character/stats.d.ts.map +1 -0
- package/dist/tools/character/stats.js +372 -0
- package/dist/tools/character/stats.js.map +1 -0
- package/dist/tools/character/templates.d.ts +22 -0
- package/dist/tools/character/templates.d.ts.map +1 -0
- package/dist/tools/character/templates.js +61 -0
- package/dist/tools/character/templates.js.map +1 -0
- package/dist/tools/character/types.d.ts +133 -0
- package/dist/tools/character/types.d.ts.map +1 -0
- package/dist/tools/character/types.js +12 -0
- package/dist/tools/character/types.js.map +1 -0
- package/dist/tools/character/vitals.d.ts +34 -0
- package/dist/tools/character/vitals.d.ts.map +1 -0
- package/dist/tools/character/vitals.js +198 -0
- package/dist/tools/character/vitals.js.map +1 -0
- package/dist/tools/character/weapons.d.ts +13 -0
- package/dist/tools/character/weapons.d.ts.map +1 -0
- package/dist/tools/character/weapons.js +79 -0
- package/dist/tools/character/weapons.js.map +1 -0
- package/dist/tools/character.d.ts +15 -3
- package/dist/tools/character.d.ts.map +1 -1
- package/dist/tools/character.js +28 -1182
- package/dist/tools/character.js.map +1 -1
- package/dist/tools/library.d.ts +32 -4
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +181 -86
- package/dist/tools/library.js.map +1 -1
- package/dist/tools/monster.d.ts +2 -0
- package/dist/tools/monster.d.ts.map +1 -1
- package/dist/tools/monster.js +4 -0
- package/dist/tools/monster.js.map +1 -1
- package/dist/tools/reference.d.ts +5 -0
- package/dist/tools/reference.d.ts.map +1 -1
- package/dist/tools/reference.js +76 -69
- package/dist/tools/reference.js.map +1 -1
- package/dist/tools/search.d.ts +1 -2
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +36 -59
- package/dist/tools/search.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the character module.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 of the character.ts refactor — see docs/character-refactor.md.
|
|
5
|
+
*
|
|
6
|
+
* `Mod`, `ClassEntry`, `InventoryItem`, `CharData` are all currently aliased
|
|
7
|
+
* to `Record<string, unknown>`. They will be tightened to proper shapes
|
|
8
|
+
* post-refactor (see follow-up A in the refactor doc) — the aliases exist so
|
|
9
|
+
* future tightening is a one-place change instead of a sweep.
|
|
10
|
+
*/
|
|
11
|
+
export type CharData = Record<string, unknown>;
|
|
12
|
+
export type Mod = Record<string, unknown>;
|
|
13
|
+
export type ClassEntry = Record<string, unknown>;
|
|
14
|
+
export type InventoryItem = Record<string, unknown>;
|
|
15
|
+
/** `type:"proficiency"` — skill/save/tool/weapon/armor/language proficiency grant. */
|
|
16
|
+
export interface ProficiencyMod {
|
|
17
|
+
type: "proficiency";
|
|
18
|
+
subType: string;
|
|
19
|
+
}
|
|
20
|
+
/** `type:"expertise"` — doubles proficiency bonus on the given skill/tool. */
|
|
21
|
+
export interface ExpertiseMod {
|
|
22
|
+
type: "expertise";
|
|
23
|
+
subType: string;
|
|
24
|
+
}
|
|
25
|
+
/** `type:"half-proficiency"` — half-prof (Jack of All Trades family). */
|
|
26
|
+
export interface HalfProficiencyMod {
|
|
27
|
+
type: "half-proficiency";
|
|
28
|
+
subType: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `type:"bonus"` — additive numeric modifier. Most varied mod type in DDB:
|
|
32
|
+
* AC, skill bonuses, ability-score buffs, HP-per-level, initiative, speed,
|
|
33
|
+
* hit/damage. The value is in `value` OR `fixedValue` (use `??` —
|
|
34
|
+
* "whichever is present"), or computed from `statId` (e.g. Gloom Stalker
|
|
35
|
+
* Dread Ambusher adds WIS mod to initiative). `bonusTypes` indicates a
|
|
36
|
+
* dynamic value source (e.g. `[1]` = use the proficiency bonus).
|
|
37
|
+
* `isGranted: false` on a race mod means the player declined the ASI
|
|
38
|
+
* (2024 floating-ASI rule).
|
|
39
|
+
*/
|
|
40
|
+
export interface BonusMod {
|
|
41
|
+
type: "bonus";
|
|
42
|
+
subType: string;
|
|
43
|
+
value?: number | null;
|
|
44
|
+
fixedValue?: number | null;
|
|
45
|
+
statId?: number | null;
|
|
46
|
+
isGranted?: boolean;
|
|
47
|
+
bonusTypes?: number[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `type:"set"` — replaces the base value (e.g. Belt of Giant Strength sets STR
|
|
51
|
+
* to 23, Boots of Striding and Springing set walking speed to 40, Draconic
|
|
52
|
+
* Resilience sets unarmored AC base via `unarmored-armor-class`).
|
|
53
|
+
* `componentId` discriminates dual-encoded set+sense pairs from same-source
|
|
54
|
+
* extensions in the sense calculation.
|
|
55
|
+
*/
|
|
56
|
+
export interface SetMod {
|
|
57
|
+
type: "set";
|
|
58
|
+
subType: string;
|
|
59
|
+
value?: number | null;
|
|
60
|
+
fixedValue?: number | null;
|
|
61
|
+
statId?: number | null;
|
|
62
|
+
componentId?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* `type:"set-base"` — baseline-establishing set, used by senses (e.g. race
|
|
66
|
+
* darkvision baseline 60 ft.). Functionally identical to `set` for the
|
|
67
|
+
* baseline pass; the distinct type exists because DDB sometimes emits both.
|
|
68
|
+
*/
|
|
69
|
+
export interface SetBaseMod {
|
|
70
|
+
type: "set-base";
|
|
71
|
+
subType: string;
|
|
72
|
+
value?: number | null;
|
|
73
|
+
fixedValue?: number | null;
|
|
74
|
+
componentId?: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* `type:"sense"` — grants or extends a sense (Darkvision, Blindsight, etc.).
|
|
78
|
+
* Pass 2 of the sense calculation uses `componentId` to decide whether the mod
|
|
79
|
+
* is a dual encoding of the baseline (take max) or an extension from a
|
|
80
|
+
* different source (additive — Gloom Stalker Umbral Sight +30 ft on race
|
|
81
|
+
* darkvision 60 ft).
|
|
82
|
+
*/
|
|
83
|
+
export interface SenseMod {
|
|
84
|
+
type: "sense";
|
|
85
|
+
subType: string;
|
|
86
|
+
value?: number | null;
|
|
87
|
+
componentId?: number;
|
|
88
|
+
}
|
|
89
|
+
/** `type:"resistance"` — damage resistance grant (e.g. "fire", "cold"). */
|
|
90
|
+
export interface ResistanceMod {
|
|
91
|
+
type: "resistance";
|
|
92
|
+
subType: string;
|
|
93
|
+
}
|
|
94
|
+
/** `type:"immunity"` — damage immunity grant (e.g. "poison", "psychic"). */
|
|
95
|
+
export interface ImmunityMod {
|
|
96
|
+
type: "immunity";
|
|
97
|
+
subType: string;
|
|
98
|
+
}
|
|
99
|
+
/** `type:"vulnerability"` — damage vulnerability grant. */
|
|
100
|
+
export interface VulnerabilityMod {
|
|
101
|
+
type: "vulnerability";
|
|
102
|
+
subType: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* `type:"language"` — language proficiency grant. The standard race/class/feat
|
|
106
|
+
* source for languages. The other two storage mechanisms (custom proficiencies
|
|
107
|
+
* with `type: 3`, and `characterValues` entries with `typeId: 35`) live
|
|
108
|
+
* outside `modifiers` and don't use this interface.
|
|
109
|
+
*/
|
|
110
|
+
export interface LanguageMod {
|
|
111
|
+
type: "language";
|
|
112
|
+
subType: string;
|
|
113
|
+
}
|
|
114
|
+
export type ParseSection = "summary" | "combat" | "spells" | "inventory" | "features" | "concentration" | "notes" | "full";
|
|
115
|
+
/**
|
|
116
|
+
* The shared context object passed to every per-domain computer module.
|
|
117
|
+
*
|
|
118
|
+
* Computed once by `computeCoreStats(char)` (Phase 2) and threaded through
|
|
119
|
+
* vitals/stats/spells/etc. Avoids each module re-deriving statMods,
|
|
120
|
+
* profBonus, allMods, etc.
|
|
121
|
+
*/
|
|
122
|
+
export interface CoreStats {
|
|
123
|
+
readonly char: CharData;
|
|
124
|
+
readonly allMods: readonly Mod[];
|
|
125
|
+
readonly statTotals: readonly number[];
|
|
126
|
+
readonly statMods: readonly number[];
|
|
127
|
+
readonly profBonus: number;
|
|
128
|
+
readonly totalLevel: number;
|
|
129
|
+
readonly classes: readonly ClassEntry[];
|
|
130
|
+
readonly inventory: readonly InventoryItem[];
|
|
131
|
+
readonly resolveTemplates: (text: string, classLevel?: number) => string;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/character/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the character module.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 of the character.ts refactor — see docs/character-refactor.md.
|
|
5
|
+
*
|
|
6
|
+
* `Mod`, `ClassEntry`, `InventoryItem`, `CharData` are all currently aliased
|
|
7
|
+
* to `Record<string, unknown>`. They will be tightened to proper shapes
|
|
8
|
+
* post-refactor (see follow-up A in the refactor doc) — the aliases exist so
|
|
9
|
+
* future tightening is a one-place change instead of a sweep.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/tools/character/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitals domain — HP, hit dice, speed (all 5 modes), initiative, death saves.
|
|
3
|
+
* Owns the vitals block.
|
|
4
|
+
*
|
|
5
|
+
* Phase 3 of the character.ts refactor — see docs/character-refactor.md.
|
|
6
|
+
*
|
|
7
|
+
* AC is its own module ([Phase 4 → ac.ts]) — `formatVitalsBlock` takes it as
|
|
8
|
+
* a separate parameter rather than including it in `Vitals`, since AC isn't
|
|
9
|
+
* a vitals concern.
|
|
10
|
+
*/
|
|
11
|
+
import type { CoreStats } from "./types.js";
|
|
12
|
+
export interface HitPoints {
|
|
13
|
+
current: number;
|
|
14
|
+
max: number;
|
|
15
|
+
temp: number;
|
|
16
|
+
}
|
|
17
|
+
export interface DeathSaves {
|
|
18
|
+
successes: number;
|
|
19
|
+
failures: number;
|
|
20
|
+
}
|
|
21
|
+
export interface Vitals {
|
|
22
|
+
hp: HitPoints;
|
|
23
|
+
hitDice: string[];
|
|
24
|
+
initiative: number;
|
|
25
|
+
speed: string[];
|
|
26
|
+
deathSaves: DeathSaves;
|
|
27
|
+
}
|
|
28
|
+
export declare function computeVitals(core: CoreStats): Vitals;
|
|
29
|
+
/**
|
|
30
|
+
* `ac` is computed by ./ac.js (Phase 4) and threaded in here separately
|
|
31
|
+
* because AC has its own module. `profBonus` is from CoreStats.
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatVitalsBlock(v: Vitals, ac: number, profBonus: number): string[];
|
|
34
|
+
//# sourceMappingURL=vitals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../../../src/tools/character/vitals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAwB,SAAS,EAAO,MAAM,YAAY,CAAC;AAEvE,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACzE,MAAM,WAAW,UAAU;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAEnE,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,SAAS,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;CACxB;AAmKD,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAQrD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAQpF"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitals domain — HP, hit dice, speed (all 5 modes), initiative, death saves.
|
|
3
|
+
* Owns the vitals block.
|
|
4
|
+
*
|
|
5
|
+
* Phase 3 of the character.ts refactor — see docs/character-refactor.md.
|
|
6
|
+
*
|
|
7
|
+
* AC is its own module ([Phase 4 → ac.ts]) — `formatVitalsBlock` takes it as
|
|
8
|
+
* a separate parameter rather than including it in `Vitals`, since AC isn't
|
|
9
|
+
* a vitals concern.
|
|
10
|
+
*/
|
|
11
|
+
import { arr, hasRemarkableAthlete, isBonusMod, isHalfProficiencyMod, isSetMod, num, obj, signed, str } from "./helpers.js";
|
|
12
|
+
// ── HP ───────────────────────────────────────────────────────────────────────
|
|
13
|
+
function computeHp(core) {
|
|
14
|
+
const { char, allMods, statMods, totalLevel } = core;
|
|
15
|
+
// baseHitPoints does NOT include the CON modifier — must add conMod × level.
|
|
16
|
+
const conMod = statMods[2];
|
|
17
|
+
// Tough feat and Dwarven Toughness grant type:"bonus" subType:"hit-points-per-level" (value 2 or 1).
|
|
18
|
+
const hpPerLevelBonus = allMods
|
|
19
|
+
.filter(m => isBonusMod(m) && m.subType === "hit-points-per-level")
|
|
20
|
+
.reduce((s, m) => s + num(m.value ?? m.fixedValue), 0);
|
|
21
|
+
// When the player rolls for HP (or manually edits their max), DDB stores the
|
|
22
|
+
// final value in `overrideHitPoints`. This already includes CON mod and any
|
|
23
|
+
// hit-points-per-level features baked in — we must NOT add them on top.
|
|
24
|
+
// `bonusHitPoints` (items, Aid, etc.) still stacks on top either way.
|
|
25
|
+
// A literal 0 is treated as "not overridden" — defensive against malformed data.
|
|
26
|
+
const override = num(char.overrideHitPoints);
|
|
27
|
+
const bonus = num(char.bonusHitPoints);
|
|
28
|
+
const max = override > 0
|
|
29
|
+
? override + bonus
|
|
30
|
+
: num(char.baseHitPoints) + bonus + ((conMod + hpPerLevelBonus) * totalLevel);
|
|
31
|
+
const current = max - num(char.removedHitPoints);
|
|
32
|
+
const temp = num(char.temporaryHitPoints);
|
|
33
|
+
return { current, max, temp };
|
|
34
|
+
}
|
|
35
|
+
// ── Hit dice ─────────────────────────────────────────────────────────────────
|
|
36
|
+
function computeHitDice(classes) {
|
|
37
|
+
return classes.map(c => {
|
|
38
|
+
const die = num(obj(c.definition).hitDice);
|
|
39
|
+
const lvl = num(c.level);
|
|
40
|
+
const used = num(c.hitDiceUsed);
|
|
41
|
+
return `${lvl}d${die} (${lvl - used} remaining)`;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// ── Speed ────────────────────────────────────────────────────────────────────
|
|
45
|
+
function computeSpeed(core) {
|
|
46
|
+
const { char, allMods } = core;
|
|
47
|
+
const weightSpeeds = obj(obj(obj(char.race).weightSpeeds).normal);
|
|
48
|
+
// Tasha's optional class features (Roving, Canny, Tireless, etc.) live in
|
|
49
|
+
// char.options.class. When preferences.enableOptionalClassFeatures is
|
|
50
|
+
// false, DDB does NOT include them in char.classes[].classFeatures, but
|
|
51
|
+
// their modifiers still appear in char.modifiers.class with
|
|
52
|
+
// `isGranted: true`. The website ignores those orphan modifiers; we must
|
|
53
|
+
// too. Discriminator: the modifier's componentId must match the id of a
|
|
54
|
+
// feature actually present in classFeatures/subclassFeatures. Hand-built
|
|
55
|
+
// fixtures don't set componentId at all (cid=0) — those bypass the filter
|
|
56
|
+
// unchanged.
|
|
57
|
+
const grantedClassFeatureIds = new Set();
|
|
58
|
+
for (const c of arr(char.classes)) {
|
|
59
|
+
for (const cf of arr(c.classFeatures)) {
|
|
60
|
+
const id = num(obj(cf.definition).id);
|
|
61
|
+
if (id)
|
|
62
|
+
grantedClassFeatureIds.add(id);
|
|
63
|
+
}
|
|
64
|
+
for (const cf of arr(obj(c.subclassDefinition).classFeatures)) {
|
|
65
|
+
const id = num(obj(cf.definition).id);
|
|
66
|
+
if (id)
|
|
67
|
+
grantedClassFeatureIds.add(id);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Build the set of modifier object identities (by reference) that originate
|
|
71
|
+
// from a class/subclass category but whose componentId is orphaned — these
|
|
72
|
+
// must be skipped. Other sources (race, feat, item, background, condition)
|
|
73
|
+
// never get filtered.
|
|
74
|
+
const skippedClassMods = new Set();
|
|
75
|
+
for (const [source, list] of Object.entries(obj(char.modifiers))) {
|
|
76
|
+
if (source !== "class" && source !== "subclass")
|
|
77
|
+
continue;
|
|
78
|
+
for (const m of arr(list)) {
|
|
79
|
+
const cid = num(m.componentId);
|
|
80
|
+
if (cid !== 0 && !grantedClassFeatureIds.has(cid))
|
|
81
|
+
skippedClassMods.add(m);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const isApplicable = (m) => !skippedClassMods.has(m);
|
|
85
|
+
// DDB uses three subType patterns for speed modifiers:
|
|
86
|
+
// - `innate-speed-{axis}` — race-granted base / overrides (e.g. Dwarven slow speed)
|
|
87
|
+
// - `speed-{axis}` — class/feat/subclass axis-specific bonus (e.g. Scout's Superior Mobility, Ranger's Roving)
|
|
88
|
+
// - `speed` (no axis suffix) — generic walking-speed bonus (e.g. Barbarian Fast Movement, Mobile feat, Longstrider)
|
|
89
|
+
// `set` mods override the base axis speed; `bonus` mods stack on top.
|
|
90
|
+
const speedCalc = (axis, base, fallback = 0) => {
|
|
91
|
+
const subTypes = new Set([`innate-speed-${axis}`, `speed-${axis}`]);
|
|
92
|
+
// The bare "speed" subType is a walking-default bonus only; never applies to fly/swim/climb/burrow.
|
|
93
|
+
if (axis === "walking")
|
|
94
|
+
subTypes.add("speed");
|
|
95
|
+
const override = allMods
|
|
96
|
+
.filter(m => isSetMod(m) && subTypes.has(m.subType) && num(m.value ?? m.fixedValue) > 0 && isApplicable(m))
|
|
97
|
+
.reduce((max, m) => Math.max(max, num(m.value ?? m.fixedValue)), 0);
|
|
98
|
+
const bonus = allMods
|
|
99
|
+
.filter(m => isBonusMod(m) && subTypes.has(m.subType) && isApplicable(m))
|
|
100
|
+
.reduce((s, m) => s + num(m.value ?? m.fixedValue), 0);
|
|
101
|
+
return (override || base || fallback) + bonus;
|
|
102
|
+
};
|
|
103
|
+
// Monk Unarmored Movement uses "unarmored-movement" rather than "innate-speed-walking".
|
|
104
|
+
// Per PHB: only applies "while you are not wearing armor or wielding a
|
|
105
|
+
// shield." Gate on the absence of any equipped item with filterType="Armor"
|
|
106
|
+
// (which covers both body armor and shields, since DDB uses armorTypeId
|
|
107
|
+
// 1/2/3 for light/medium/heavy and 4 for shield, all under the same
|
|
108
|
+
// filterType).
|
|
109
|
+
const hasEquippedArmorOrShield = arr(char.inventory).some(i => i.equipped === true && str(obj(i.definition).filterType) === "Armor");
|
|
110
|
+
const unarmoredMoveBonus = hasEquippedArmorOrShield
|
|
111
|
+
? 0
|
|
112
|
+
: allMods
|
|
113
|
+
.filter(m => isBonusMod(m) && m.subType === "unarmored-movement" && isApplicable(m))
|
|
114
|
+
.reduce((s, m) => s + num(m.value ?? m.fixedValue), 0);
|
|
115
|
+
const walkSpeed = speedCalc("walking", num(weightSpeeds.walk), 30) + unarmoredMoveBonus;
|
|
116
|
+
const flySpeed = speedCalc("flying", num(weightSpeeds.fly));
|
|
117
|
+
const swimSpeed = speedCalc("swimming", num(weightSpeeds.swim));
|
|
118
|
+
const climbSpeed = speedCalc("climbing", num(weightSpeeds.climb));
|
|
119
|
+
const burrowSpeed = speedCalc("burrowing", num(weightSpeeds.burrow));
|
|
120
|
+
const parts = [`${walkSpeed} ft.`];
|
|
121
|
+
if (flySpeed > 0)
|
|
122
|
+
parts.push(`fly ${flySpeed} ft.`);
|
|
123
|
+
if (swimSpeed > 0)
|
|
124
|
+
parts.push(`swim ${swimSpeed} ft.`);
|
|
125
|
+
if (climbSpeed > 0)
|
|
126
|
+
parts.push(`climb ${climbSpeed} ft.`);
|
|
127
|
+
if (burrowSpeed > 0)
|
|
128
|
+
parts.push(`burrow ${burrowSpeed} ft.`);
|
|
129
|
+
return parts;
|
|
130
|
+
}
|
|
131
|
+
// ── Initiative ───────────────────────────────────────────────────────────────
|
|
132
|
+
function computeInitiative(core) {
|
|
133
|
+
const { allMods, statMods, classes, profBonus } = core;
|
|
134
|
+
const dexMod = statMods[1];
|
|
135
|
+
const initiativeBonus = allMods
|
|
136
|
+
.filter(m => isBonusMod(m) && m.subType === "initiative")
|
|
137
|
+
.reduce((s, m) => {
|
|
138
|
+
// bonusTypes [1] means the bonus value is the proficiency bonus, not a fixed number
|
|
139
|
+
const usesProfBonus = arr(m.bonusTypes).includes(1) && (m.fixedValue == null && m.value == null);
|
|
140
|
+
if (usesProfBonus)
|
|
141
|
+
return s + profBonus;
|
|
142
|
+
if (m.value != null)
|
|
143
|
+
return s + num(m.value);
|
|
144
|
+
if (m.fixedValue != null)
|
|
145
|
+
return s + num(m.fixedValue);
|
|
146
|
+
// statId-based bonus (e.g. Gloom Stalker Dread Ambusher adds WIS mod to initiative)
|
|
147
|
+
const sid = num(m.statId);
|
|
148
|
+
return s + (sid > 0 ? statMods[sid - 1] : 0);
|
|
149
|
+
}, 0);
|
|
150
|
+
// Half-proficiency to initiative comes from two distinct sources:
|
|
151
|
+
//
|
|
152
|
+
// 1. Bard's Jack of All Trades emits an explicit
|
|
153
|
+
// `type:"half-proficiency" subType:"initiative"` modifier (in addition
|
|
154
|
+
// to its `subType:"ability-checks"` modifier that drives skills).
|
|
155
|
+
// PHB rule: round DOWN.
|
|
156
|
+
// 2. Champion Fighter's Remarkable Athlete emits NO modifier at all —
|
|
157
|
+
// detection is by subclass name + level (see hasRemarkableAthlete).
|
|
158
|
+
// PHB rule: round UP.
|
|
159
|
+
//
|
|
160
|
+
// We must NOT infer initiative half-prof from `subType:"ability-checks"`
|
|
161
|
+
// alone — the DDB website doesn't. If a character has both JoAT and RA
|
|
162
|
+
// somehow (Bard 2 / Champion 7 multiclass), take the max rather than
|
|
163
|
+
// double-stacking.
|
|
164
|
+
const joatInit = allMods.some(m => isHalfProficiencyMod(m) && m.subType === "initiative")
|
|
165
|
+
? Math.floor(profBonus / 2)
|
|
166
|
+
: 0;
|
|
167
|
+
const raInit = hasRemarkableAthlete(classes) ? Math.ceil(profBonus / 2) : 0;
|
|
168
|
+
return dexMod + initiativeBonus + Math.max(joatInit, raInit);
|
|
169
|
+
}
|
|
170
|
+
// ── Death saves ──────────────────────────────────────────────────────────────
|
|
171
|
+
function computeDeathSaves(char) {
|
|
172
|
+
const ds = obj(char.deathSaves);
|
|
173
|
+
return { successes: num(ds.successCount), failures: num(ds.failCount) };
|
|
174
|
+
}
|
|
175
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
176
|
+
export function computeVitals(core) {
|
|
177
|
+
return {
|
|
178
|
+
hp: computeHp(core),
|
|
179
|
+
hitDice: computeHitDice(core.classes),
|
|
180
|
+
initiative: computeInitiative(core),
|
|
181
|
+
speed: computeSpeed(core),
|
|
182
|
+
deathSaves: computeDeathSaves(core.char),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* `ac` is computed by ./ac.js (Phase 4) and threaded in here separately
|
|
187
|
+
* because AC has its own module. `profBonus` is from CoreStats.
|
|
188
|
+
*/
|
|
189
|
+
export function formatVitalsBlock(v, ac, profBonus) {
|
|
190
|
+
return [
|
|
191
|
+
`HP: ${v.hp.current}/${v.hp.max} Temp HP: ${v.hp.temp || "—"} Prof Bonus: ${signed(profBonus)}`,
|
|
192
|
+
`Hit Dice: ${v.hitDice.join(" / ")}`,
|
|
193
|
+
`AC: ${ac} Initiative: ${signed(v.initiative)} Speed: ${v.speed.join(", ")}`,
|
|
194
|
+
`Death Saves: Successes ${v.deathSaves.successes}/3 Failures ${v.deathSaves.failures}/3`,
|
|
195
|
+
``,
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=vitals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.js","sourceRoot":"","sources":["../../../src/tools/character/vitals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weapons domain — weapon attack rolls for equipped inventory weapons.
|
|
3
|
+
*
|
|
4
|
+
* Phase 6a of the character.ts refactor — see docs/character-refactor.md.
|
|
5
|
+
*
|
|
6
|
+
* Owns ability-mod selection (finesse, ranged, Martial Arts monk weapons),
|
|
7
|
+
* proficiency bonus, magic enhancement (+1/+2/+3 from grantedModifiers), and
|
|
8
|
+
* duplicate consolidation (×2 daggers, etc.). Output is pre-formatted lines
|
|
9
|
+
* to preserve byte-for-byte parity with the original inline code.
|
|
10
|
+
*/
|
|
11
|
+
import type { CoreStats } from "./types.js";
|
|
12
|
+
export declare function computeWeaponAttacks(core: CoreStats): string[];
|
|
13
|
+
//# sourceMappingURL=weapons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weapons.d.ts","sourceRoot":"","sources":["../../../src/tools/character/weapons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAgF9D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weapons domain — weapon attack rolls for equipped inventory weapons.
|
|
3
|
+
*
|
|
4
|
+
* Phase 6a of the character.ts refactor — see docs/character-refactor.md.
|
|
5
|
+
*
|
|
6
|
+
* Owns ability-mod selection (finesse, ranged, Martial Arts monk weapons),
|
|
7
|
+
* proficiency bonus, magic enhancement (+1/+2/+3 from grantedModifiers), and
|
|
8
|
+
* duplicate consolidation (×2 daggers, etc.). Output is pre-formatted lines
|
|
9
|
+
* to preserve byte-for-byte parity with the original inline code.
|
|
10
|
+
*/
|
|
11
|
+
import { arr, isBonusMod, isProficiencyMod, num, obj, signed, str } from "./helpers.js";
|
|
12
|
+
export function computeWeaponAttacks(core) {
|
|
13
|
+
const { allMods, classes, inventory, statMods, profBonus } = core;
|
|
14
|
+
const dexMod = statMods[1];
|
|
15
|
+
const weaponProfSlugs = new Set(allMods.filter(isProficiencyMod).map(m => m.subType));
|
|
16
|
+
const isWeaponProficient = (def) => {
|
|
17
|
+
const catId = num(def.categoryId); // 1=simple, 2=martial
|
|
18
|
+
const typeName = str(def.type).toLowerCase().replace(/[,\s]+/g, "-");
|
|
19
|
+
return (catId === 1 && weaponProfSlugs.has("simple-weapons")) ||
|
|
20
|
+
(catId === 2 && weaponProfSlugs.has("martial-weapons")) ||
|
|
21
|
+
weaponProfSlugs.has(typeName);
|
|
22
|
+
};
|
|
23
|
+
// Martial Arts: allows DEX for monk weapons (simple melee + shortsword, no Two-Handed/Heavy)
|
|
24
|
+
const hasMartialArts = allMods.some(m => str(m.subType) === "martial-arts") ||
|
|
25
|
+
classes.some(c => arr(c.classFeatures).some(cf => str(obj(cf.definition).name) === "Martial Arts" &&
|
|
26
|
+
num(obj(cf.definition).requiredLevel || 1) <= num(c.level)));
|
|
27
|
+
const weaponInventoryMap = new Map();
|
|
28
|
+
for (const i of inventory) {
|
|
29
|
+
const def = obj(i.definition);
|
|
30
|
+
if (str(def.filterType) !== "Weapon")
|
|
31
|
+
continue;
|
|
32
|
+
if (i.equipped !== true)
|
|
33
|
+
continue; // only show equipped weapons in ACTIONS
|
|
34
|
+
const wName = str(def.name);
|
|
35
|
+
const dmg = obj(def.damage);
|
|
36
|
+
const dmgDice = str(dmg.diceString);
|
|
37
|
+
const dmgType = str(def.damageType).toLowerCase();
|
|
38
|
+
const attackType = num(def.attackType); // 1=melee, 2=ranged
|
|
39
|
+
const props = arr(def.properties).map(p => str(p.name));
|
|
40
|
+
const isFinesse = props.includes("Finesse");
|
|
41
|
+
const isRanged = attackType === 2;
|
|
42
|
+
const range = num(def.range);
|
|
43
|
+
const longRange = num(def.longRange);
|
|
44
|
+
const mastery = str(def.mastery);
|
|
45
|
+
// Magic enhancement bonus from grantedModifiers (e.g. +1 weapon)
|
|
46
|
+
const magicBonus = arr(def.grantedModifiers)
|
|
47
|
+
.filter(gm => isBonusMod(gm) && gm.subType === "magic")
|
|
48
|
+
.reduce((s, gm) => s + num(gm.value ?? gm.fixedValue), 0);
|
|
49
|
+
// Monk weapons: simple melee or shortsword, no Two-Handed/Heavy
|
|
50
|
+
const isMonkWeapon = hasMartialArts &&
|
|
51
|
+
!props.includes("Two-Handed") && !props.includes("Heavy") &&
|
|
52
|
+
((num(def.categoryId) === 1 && attackType === 1) || str(def.name) === "Shortsword");
|
|
53
|
+
// Ability modifier for attack/damage
|
|
54
|
+
const usesDex = isRanged || ((isFinesse || isMonkWeapon) && dexMod > statMods[0]);
|
|
55
|
+
const abilityMod = usesDex ? dexMod : statMods[0];
|
|
56
|
+
const profMod = isWeaponProficient(def) ? profBonus : 0;
|
|
57
|
+
const hitBonus = abilityMod + profMod + magicBonus;
|
|
58
|
+
const dmgBonus = abilityMod + magicBonus;
|
|
59
|
+
const dmgStr = dmgBonus !== 0 ? `${dmgDice}${signed(dmgBonus)}` : dmgDice;
|
|
60
|
+
const rangeStr = isRanged ? `range ${range}/${longRange} ft.` : `reach 5 ft.`;
|
|
61
|
+
const propsStr = [...props, ...(mastery ? [mastery] : [])].join(", ");
|
|
62
|
+
const line = `• ${wName.padEnd(16)} ${signed(hitBonus)} to hit ${dmgStr} ${dmgType} ${rangeStr}${propsStr ? ` ${propsStr}` : ""}`;
|
|
63
|
+
// Consolidate duplicates by key
|
|
64
|
+
const key = wName + dmgDice;
|
|
65
|
+
const existing = weaponInventoryMap.get(key);
|
|
66
|
+
if (existing) {
|
|
67
|
+
existing.qty += num(i.quantity) || 1;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
weaponInventoryMap.set(key, { lines: [line], qty: num(i.quantity) || 1 });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const weaponAttacks = [];
|
|
74
|
+
for (const { lines, qty } of weaponInventoryMap.values()) {
|
|
75
|
+
weaponAttacks.push(qty > 1 ? lines[0].replace("•", `• ×${qty}`) : lines[0]);
|
|
76
|
+
}
|
|
77
|
+
return weaponAttacks;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=weapons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weapons.js","sourceRoot":"","sources":["../../../src/tools/character/weapons.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API surface for character tools. The 1000-line `parseCharacterData`
|
|
3
|
+
* and 220-line `getDefinition` that used to live here have been carved into
|
|
4
|
+
* per-domain modules under `./character/` — see docs/character-refactor.md.
|
|
5
|
+
*
|
|
6
|
+
* What stays here: network/IO (getCharacter, downloadCharacter,
|
|
7
|
+
* listCharacters, findCharacterByName), the in-process JSON cache, and
|
|
8
|
+
* thin re-exports of the moved entry points.
|
|
9
|
+
*/
|
|
10
|
+
import type { ParseSection } from "./character/types.js";
|
|
11
|
+
export { parseCharacterData } from "./character/parse.js";
|
|
12
|
+
export { getDefinition } from "./character/definition.js";
|
|
13
|
+
/** Wipe the in-process character JSON cache. */
|
|
14
|
+
export declare function clearCharacterCache(): void;
|
|
1
15
|
/**
|
|
2
16
|
* Resolve a character name to a numeric ID using the character list API.
|
|
3
17
|
* Resolution order: exact match → substring match → Levenshtein ≤3 on full
|
|
@@ -8,8 +22,7 @@ export declare function findCharacterByName(name: string): Promise<{
|
|
|
8
22
|
id: string;
|
|
9
23
|
name: string;
|
|
10
24
|
} | null>;
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function parseCharacter(characterId: string, sections?: "summary" | "combat" | "spells" | "inventory" | "features" | "concentration" | "notes" | "full"): Promise<string>;
|
|
25
|
+
export declare function parseCharacter(characterId: string, sections?: ParseSection): Promise<string>;
|
|
13
26
|
/**
|
|
14
27
|
* Fetch raw character JSON from the DnD Beyond API.
|
|
15
28
|
* Uses saved session cookies — no browser needed after initial login.
|
|
@@ -17,5 +30,4 @@ export declare function parseCharacter(characterId: string, sections?: "summary"
|
|
|
17
30
|
export declare function getCharacter(characterId: string): Promise<string>;
|
|
18
31
|
export declare function downloadCharacter(characterId: string, outputPath?: string): Promise<string>;
|
|
19
32
|
export declare function listCharacters(): Promise<string>;
|
|
20
|
-
export declare function getDefinition(characterId: string, query: string): Promise<string>;
|
|
21
33
|
//# sourceMappingURL=character.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"character.d.ts","sourceRoot":"","sources":["../../src/tools/character.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"character.d.ts","sourceRoot":"","sources":["../../src/tools/character.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAQzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAW1D,gDAAgD;AAChD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAoCpG;AAED,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,YAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAqDjB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAkCtD"}
|