@iamjameslennon/ddb-mcp 2.8.0 → 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/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -4
- package/dist/browser.js.map +1 -1
- package/dist/index.js +10 -18
- package/dist/index.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 +13 -3
- package/dist/tools/character.d.ts.map +1 -1
- package/dist/tools/character.js +18 -1181
- 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/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 @@
|
|
|
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,15 @@
|
|
|
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";
|
|
1
13
|
/** Wipe the in-process character JSON cache. */
|
|
2
14
|
export declare function clearCharacterCache(): void;
|
|
3
15
|
/**
|
|
@@ -10,8 +22,7 @@ export declare function findCharacterByName(name: string): Promise<{
|
|
|
10
22
|
id: string;
|
|
11
23
|
name: string;
|
|
12
24
|
} | null>;
|
|
13
|
-
export declare function
|
|
14
|
-
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>;
|
|
15
26
|
/**
|
|
16
27
|
* Fetch raw character JSON from the DnD Beyond API.
|
|
17
28
|
* Uses saved session cookies — no browser needed after initial login.
|
|
@@ -19,5 +30,4 @@ export declare function parseCharacter(characterId: string, sections?: "summary"
|
|
|
19
30
|
export declare function getCharacter(characterId: string): Promise<string>;
|
|
20
31
|
export declare function downloadCharacter(characterId: string, outputPath?: string): Promise<string>;
|
|
21
32
|
export declare function listCharacters(): Promise<string>;
|
|
22
|
-
export declare function getDefinition(characterId: string, query: string): Promise<string>;
|
|
23
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"}
|