Switch PF2e data source from Pf2eTools to Foundry VTT PF2e
Replace the stagnant Pf2eTools bestiary with Foundry VTT PF2e system data (github.com/foundryvtt/pf2e, v13-dev branch). This gives us 4,355 remaster-era creatures across 49 sources including Monster Core 1+2 and all adventure paths. Changes: - Rewrite index generation script to walk Foundry pack directories - Rewrite PF2e normalization adapter for Foundry JSON shape (system.* fields, items[] for attacks/abilities/spells) - Add stripFoundryTags utility for Foundry HTML + enrichment syntax - Implement multi-file source fetching (one request per creature file) - Add spellcasting section to PF2e stat block (ranked spells + cantrips) - Add saveConditional and hpDetails to PF2e domain type and stat block - Add size and rarity to PF2e trait tags - Filter redundant glossary abilities (healing when in hp.details, spell mechanic reminders, allSaves duplicates) - Add PF2e stat block component tests (22 tests) - Bump IndexedDB cache version to 5 for clean migration Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,10 +9,7 @@ import {
|
||||
normalizeBestiary,
|
||||
setSourceDisplayNames,
|
||||
} from "../adapters/bestiary-adapter.js";
|
||||
import {
|
||||
normalizePf2eBestiary,
|
||||
setPf2eSourceDisplayNames,
|
||||
} from "../adapters/pf2e-bestiary-adapter.js";
|
||||
import { normalizeFoundryCreatures } from "../adapters/pf2e-bestiary-adapter.js";
|
||||
import { useAdapters } from "../contexts/adapter-context.js";
|
||||
import { useRulesEditionContext } from "../contexts/rules-edition-context.js";
|
||||
|
||||
@@ -52,7 +49,6 @@ export function useBestiary(): BestiaryHook {
|
||||
setSourceDisplayNames(index.sources as Record<string, string>);
|
||||
|
||||
const pf2eIndex = pf2eBestiaryIndex.loadIndex();
|
||||
setPf2eSourceDisplayNames(pf2eIndex.sources as Record<string, string>);
|
||||
|
||||
if (index.creatures.length > 0 || pf2eIndex.creatures.length > 0) {
|
||||
setIsLoaded(true);
|
||||
@@ -113,17 +109,40 @@ export function useBestiary(): BestiaryHook {
|
||||
|
||||
const fetchAndCacheSource = useCallback(
|
||||
async (sourceCode: string, url: string): Promise<void> => {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch: ${response.status} ${response.statusText}`,
|
||||
let creatures: AnyCreature[];
|
||||
|
||||
if (edition === "pf2e") {
|
||||
// PF2e: url is a base URL; fetch each creature file in parallel
|
||||
const paths = pf2eBestiaryIndex.getCreaturePathsForSource(sourceCode);
|
||||
const baseUrl = url.endsWith("/") ? url : `${url}/`;
|
||||
const responses = await Promise.all(
|
||||
paths.map(async (path) => {
|
||||
const response = await fetch(`${baseUrl}${path}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch ${path}: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
return response.json();
|
||||
}),
|
||||
);
|
||||
const displayName = pf2eBestiaryIndex.getSourceDisplayName(sourceCode);
|
||||
creatures = normalizeFoundryCreatures(
|
||||
responses,
|
||||
sourceCode,
|
||||
displayName,
|
||||
);
|
||||
} else {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
const json = await response.json();
|
||||
creatures = normalizeBestiary(json);
|
||||
}
|
||||
const json = await response.json();
|
||||
const creatures =
|
||||
edition === "pf2e"
|
||||
? normalizePf2eBestiary(json)
|
||||
: normalizeBestiary(json);
|
||||
|
||||
const displayName =
|
||||
edition === "pf2e"
|
||||
? pf2eBestiaryIndex.getSourceDisplayName(sourceCode)
|
||||
@@ -149,7 +168,11 @@ export function useBestiary(): BestiaryHook {
|
||||
async (sourceCode: string, jsonData: unknown): Promise<void> => {
|
||||
const creatures =
|
||||
edition === "pf2e"
|
||||
? normalizePf2eBestiary(jsonData as { creature: unknown[] })
|
||||
? normalizeFoundryCreatures(
|
||||
Array.isArray(jsonData) ? jsonData : [jsonData],
|
||||
sourceCode,
|
||||
pf2eBestiaryIndex.getSourceDisplayName(sourceCode),
|
||||
)
|
||||
: normalizeBestiary(
|
||||
jsonData as Parameters<typeof normalizeBestiary>[0],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user