import { readFileSync, writeFileSync, readdirSync } from 'node:fs'; import { buildMonsterModel, modelEntryId } from './lib/monster-model.mjs'; // 적 18종 각각의 전용 모델(.model) emit. 단일 소스: data/enemies.json(appearance) + ChaseMonster.model(골격). const OUT_DIR = 'RootDesk/MyDesk/Models/Monsters'; const enemies = JSON.parse(readFileSync('data/enemies.json', 'utf8')).enemies; const skeleton = JSON.parse(readFileSync('Global/ChaseMonster.model', 'utf8')); // EntryKey 충돌 가드 (LEA-3015 예방): 기존 .model들의 EntryKey 수집 (경로별) const existing = []; // { key, path } for (const dir of ['Global', OUT_DIR]) { for (const f of readdirSync(dir).filter((n) => n.endsWith('.model'))) { const path = `${dir}/${f}`; existing.push({ key: JSON.parse(readFileSync(path, 'utf8')).EntryKey, path }); } } const written = []; const skipped = []; for (const [enemyId, enemy] of Object.entries(enemies)) { if (!enemy.appearance) { skipped.push(enemyId); continue; } const file = buildMonsterModel(enemyId, enemy, skeleton); const outPath = `${OUT_DIR}/${enemyId}.model`; const clash = existing.find((e) => e.key === file.EntryKey && e.path !== outPath); if (clash) throw new Error(`[gen-monster-models] EntryKey 충돌: ${file.EntryKey} (기존 ${clash.path})`); writeFileSync(outPath, JSON.stringify(file, null, 2) + '\n', 'utf8'); written.push(enemyId); } console.log(`[gen-monster-models] ${written.length}종 emit${skipped.length ? ` / appearance 없음 스킵: ${skipped.join(', ')}` : ''}`);