/**
* Примерка AI-атласа в игре ДО promote: временно подменяет целевой атлас
* сборкой из build/<id>/, снимает скриншот героя в локации, возвращает файлы.
* Апрув по обзорному листу — пиксели на клетке; примерка показывает якорь,
* масштаб и палитру в контексте мира.
*
* node tryon.mjs <id> [файл-скриншота=/tmp/rpg_tryon.png]
*
* Файлы assets восстанавливаются в finally (даже при падении).
*/
import { readFileSync, writeFileSync, copyFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { startDevServer, openGame } from '../lib.mjs';
const HERE = fileURLToPath(new URL('.', import.meta.url));
const id = process.argv[2] ?? 'bellringer';
const shot = process.argv[3] ?? '/tmp/rpg_tryon.png';
// Цель берём из манифеста (target), как её видит promote.
const manifest = JSON.parse(readFileSync(join(HERE, 'atlas-manifest.json'), 'utf8'));
const char = manifest.characters.find((c) => c.id === id);
if (!char) throw new Error(`персонаж «${id}» не найден в atlas-manifest.json`);
const buildPng = join(HERE, 'build', id, char.target);
if (!existsSync(buildPng)) throw new Error(`нет сборки ${buildPng} — сначала atlas.mjs build ${id}`);
const dst = join(HERE, '..', '..', 'assets');
const dstPng = join(dst, char.target);
const dstJson = dstPng.replace(/\.png$/, '.json');
const backup = {
png: existsSync(dstPng) ? readFileSync(dstPng) : null,
json: existsSync(dstJson) ? readFileSync(dstJson) : null
};
let server = null, browser = null;
try {
copyFileSync(buildPng, dstPng);
// Игра ждёт кадры с префиксом hero_ (LocationScene: hero_down/up/side) —
// переписываем имена кадров сборки в JSON-копии.
const atlasJson = JSON.parse(readFileSync(join(HERE, 'build', id, char.target.replace(/\.png$/, '.json')), 'utf8'));
atlasJson.frames = Object.fromEntries(
Object.entries(atlasJson.frames).map(([k, v]) => [k.replace(new RegExp(`^${id}_`), 'hero_'), v])
);
writeFileSync(dstJson, JSON.stringify(atlasJson));
console.log(`[tryon] ${char.target} подменён сборкой «${id}» (status: ${char.status}, кадры → hero_*)`);
server = await startDevServer({ port: 5199 });
const { browser: b, page, agent } = await openGame({ url: server.url, newGame: true });
browser = b;
await agent.step(60); // пара шагов, чтобы герой попал в кадр ходьбы
const snap = await agent.snapshot();
console.log('снапшот:', JSON.stringify({ area: snap.area, hero: snap.hero?.tile }));
await page.screenshot({ path: shot });
console.log(`Скриншот: ${shot}`);
} finally {
if (backup.png) writeFileSync(dstPng, backup.png);
if (backup.json) writeFileSync(dstJson, backup.json);
if (backup.png === null) console.log('[tryon] внимание: исходного атласа не было — проверь assets вручную');
if (browser) await browser.close();
if (server) server.stop();
}