c343fd3cd0
D&D creatures listed in data/bestiary/dnd-bundled.json are now merged into the search index and pre-loaded into creatureMap, so they appear alongside 5etools creatures with no "Load source" step. Source codes are derived from the JSON itself (each creature carries source + sourceDisplayName), so adding a new book is a pure data change. Bundled sources are excluded from getAllSourceCodes() so bulk-import skips them, and they never appear in the source manager (which only lists cached sources). Includes a reference extractor (scripts/extract-great-labors.py) for the 5.5e revised stat-block format and a /bundle-bestiary skill that future agents can follow to add monsters from other PDF books. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import type { BestiaryIndexEntry, Creature } from "@initiative/domain";
|
|
import { creatureId } from "@initiative/domain";
|
|
|
|
import rawBundled from "../../../../data/bestiary/dnd-bundled.json";
|
|
|
|
type RawBundledCreature = Omit<Creature, "id"> & { id: string };
|
|
|
|
const SIZE_TO_CODE: Record<string, string> = {
|
|
Tiny: "T",
|
|
Small: "S",
|
|
Medium: "M",
|
|
Large: "L",
|
|
Huge: "H",
|
|
Gargantuan: "G",
|
|
};
|
|
|
|
/** Full normalized stat blocks for bundled D&D creatures. */
|
|
export function loadBundledDndCreatures(): Creature[] {
|
|
return (rawBundled as RawBundledCreature[]).map((c) => ({
|
|
...c,
|
|
id: creatureId(c.id),
|
|
}));
|
|
}
|
|
|
|
/** Index entries derived from the bundled creatures, in the compact shape
|
|
* used by the search index. */
|
|
export function loadBundledDndIndexEntries(): BestiaryIndexEntry[] {
|
|
return (rawBundled as RawBundledCreature[]).map((c) => ({
|
|
name: c.name,
|
|
source: c.source,
|
|
ac: c.ac,
|
|
hp: c.hp.average,
|
|
dex: c.abilities.dex,
|
|
cr: c.cr,
|
|
initiativeProficiency: c.initiativeProficiency,
|
|
size: SIZE_TO_CODE[c.size.split(" ")[0]] ?? "M",
|
|
type: c.type.split(" ")[0].toLowerCase(),
|
|
}));
|
|
}
|
|
|
|
/** Source codes → display names, derived from the bundled creatures' own
|
|
* `source` and `sourceDisplayName` fields. Adding a new book just means
|
|
* appending creatures with the right `source` field to dnd-bundled.json;
|
|
* no code change is required here. */
|
|
export function getBundledDndSources(): ReadonlyMap<string, string> {
|
|
const map = new Map<string, string>();
|
|
for (const c of rawBundled as RawBundledCreature[]) {
|
|
if (!map.has(c.source)) {
|
|
map.set(c.source, c.sourceDisplayName);
|
|
}
|
|
}
|
|
return map;
|
|
}
|