feat(npcs): add groups, storyline bindings, and Foundry import
Nested NPC groups with color, graph filter, and scene/storyline binding; Foundry worlds/modules import actors into groups; storyline merge asks on NPC name conflicts and reports NPC counts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import type { FoundryCompatibility, FoundryPackageManifest } from './foundryTypes';
|
||||
|
||||
/** Актуальные major-версии Foundry, которые поддерживает импортёр. */
|
||||
export const FOUNDRY_SUPPORTED_MAJORS = new Set([11, 12, 13]);
|
||||
|
||||
function parseMajor(version: string | undefined): number | null {
|
||||
if (!version || typeof version !== 'string') return null;
|
||||
const m = /^(\d+)/u.exec(version.trim());
|
||||
if (!m) return null;
|
||||
const n = Number(m[1]);
|
||||
return Number.isFinite(n) ? n : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* true — пакет выглядит как актуальный (v11+).
|
||||
* Если версия не указана — разрешаем (попробуем прочитать данные).
|
||||
* Если явно только старая (<11) — отклоняем.
|
||||
*/
|
||||
export function isSupportedFoundryPackage(
|
||||
manifest: Pick<FoundryPackageManifest, 'compatibility' | 'coreVersion'>,
|
||||
): {
|
||||
ok: boolean;
|
||||
reason?: string;
|
||||
} {
|
||||
const compat: FoundryCompatibility = manifest.compatibility ?? {};
|
||||
const majors = [compat.minimum, compat.verified, compat.maximum, manifest.coreVersion]
|
||||
.map(parseMajor)
|
||||
.filter((n): n is number => n !== null);
|
||||
|
||||
if (majors.length === 0) return { ok: true };
|
||||
|
||||
const maxMajor = Math.max(...majors);
|
||||
const minMajor = Math.min(...majors);
|
||||
|
||||
// Явно только до v10 и ниже.
|
||||
if (typeof compat.maximum === 'string') {
|
||||
const max = parseMajor(compat.maximum);
|
||||
if (max !== null && max < 11) {
|
||||
return {
|
||||
ok: false,
|
||||
reason: `Пакет Foundry слишком старый (maximum ${compat.maximum}). Нужна версия 11+.`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (maxMajor < 11) {
|
||||
return {
|
||||
ok: false,
|
||||
reason: `Пакет Foundry слишком старый (обнаружена версия ${String(maxMajor)}). Нужна версия 11+.`,
|
||||
};
|
||||
}
|
||||
|
||||
// Если минимум уже далеко в будущем — всё равно пробуем, если пересекается с 11–13.
|
||||
const overlapsSupported = majors.some((m) => FOUNDRY_SUPPORTED_MAJORS.has(m)) || minMajor <= 13;
|
||||
if (!overlapsSupported) {
|
||||
return {
|
||||
ok: false,
|
||||
reason: `Версия Foundry не поддерживается импортом (нужны 11–13).`,
|
||||
};
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
}
|
||||
Reference in New Issue
Block a user