Newer
Older
rpg / tools / checks / transitions.mjs
/**
 * Сценарий transitions — единый механизм переходов.
 * 1) step-переход: пешком в Звенец -> area==='zvenets'.
 * 2) клик-переход: клик по колодцу у дома Ирвина -> телепорт на луга (entry (22,21)).
 * 3) обратный колодец: клик по луговому колодцу -> возврат в Звенец.
 * 4) снапшот перечисляет переходы области с триггерами.
 * Запуск: node tools/agent.mjs run tools/checks/transitions.mjs
 */
import { startDevServer, openGame, Checks } from '../agent-lib.mjs';

export default async function ({ pretty }) {
    const c = new Checks('transitions');
    const server = await startDevServer();
    let ctx;
    try {
        await c.run('step-переход: луга -> Звенец пешком', async () => {
            ctx = await openGame({ url: server.url, newGame: true });
            // Спим врагов, чтобы путь был безопасным; идём к тропе (26,14).
            await ctx.agent.command('scene:sleepAll');
            const walked = await ctx.agent.walkTo(26, 14, { timeoutTicks: 3000 });
            c.expect(walked, 'walkTo(26,14) не дошёл');
            const w = await ctx.agent.waitFor('s.area === "zvenets"', { timeoutTicks: 600 });
            c.expect(w.ok, 'после тропы не в Звенце', { area: w.snapshot.area });
            await ctx.agent.waitFor('!s.transitioning', { timeoutTicks: 600 });
            return null;
        });
        await c.run('клик-переход: колодец Звенца -> луга', async () => {
            // Колодец (9,6) у дома Ирвина; entry на лугах — (22,21).
            await ctx.agent.waitFor('!s.transitioning', { timeoutTicks: 600 });
            await ctx.agent.tapTile(9, 6);
            const w = await ctx.agent.waitFor('s.area === "meadows"', { timeoutTicks: 1200 });
            c.expect(w.ok, 'колодец не телепортировал на луга', { area: w.snapshot.area });
            await ctx.agent.waitFor('!s.transitioning', { timeoutTicks: 600 });
            const s = await ctx.agent.snapshot();
            c.expect(s.hero.tile.x === 22 && s.hero.tile.y === 21, 'герой не на entry (22,21)', s.hero.tile);
            return null;
        });
        await c.run('обратный колодец: луга -> Звенец', async () => {
            // Луговой колодец (22,20) стоит рядом с entry — кликаем по нему.
            await ctx.agent.tapTile(22, 20);
            const w = await ctx.agent.waitFor('s.area === "zvenets"', { timeoutTicks: 1200 });
            c.expect(w.ok, 'луговой колодец не вернул в Звенец', { area: w.snapshot.area });
            await ctx.agent.waitFor('!s.transitioning', { timeoutTicks: 600 });
            const s = await ctx.agent.snapshot();
            c.expect(s.hero.tile.x === 9 && s.hero.tile.y === 7, 'герой не на entry (9,7) Звенца', s.hero.tile);
            return null;
        });
        await c.run('снапшот: переходы области с триггерами', async () => {
            const s = await ctx.agent.snapshot();
            const wells = (s.transitions ?? []).filter((t) => t.trigger === 'click');
            c.expect(wells.length >= 1, 'нет click-переходов в снапшоте', s.transitions);
            c.expect(
                (s.transitions ?? []).every((t) => typeof t.to === 'string' && t.to.length > 0),
                'переход без цели',
                s.transitions
            );
            return null;
        });
    } finally {
        await ctx?.browser?.close();
        server.stop();
    }
    return c.finish({ pretty }).ok ? 0 : 1;
}