import { describe, expect, it } from 'vitest' import { World } from '../src/renderer/game/engine/runtime/World' import { resolveBreakthrough } from '../src/renderer/game/engine/runtime/Systems/cultivation' import { resolveRaid } from '../src/renderer/game/engine/runtime/Systems/combat' import { MAJORS } from '../src/renderer/game/data/realms' function busOf(w: World): string[] { const got: string[] = [] w.out.push({ onLog: () => undefined, onChronicle: () => undefined, onBattle: () => undefined, onPendingEvent: () => undefined, onGameOver: () => undefined, onFx: (em) => got.push(em.kind) }) return got } describe('特效语义发射(引擎侧唯一源)', () => { it('突破成功 → spark(语义点,非文本正则)', () => { const w = World.create({ seed: 'fx-1', surname: '叶', familyName: '叶家', motto: 'm', difficulty: 'normal' }) const got = busOf(w) const c = Object.values(w.state.members)[0]! c.realm = { major: 'qi', minor: MAJORS.qi.minorLayers - 1 } c.realmProgress = 100 c.health = 100 resolveBreakthrough(w, c, 99) // 必成 expect(got).toContain('spark') }) it('劫掠大胜 → blade;劫掠失利 → pulse', () => { const w = World.create({ seed: 'fx-2', surname: '柳', familyName: '柳家', motto: 'm', difficulty: 'normal' }) const got = busOf(w) const npcId = Object.keys(w.state.npcFamilies)[0]! const team = [w.state.members['x1']!, w.state.members['x2']!, w.state.members['x3']!, w.state.members['x4']!] for (const c of team) { c.realm = { major: 'spirit', minor: 0 } c.health = 100 } resolveRaid(w, npcId, team) expect(got).toContain('blade') }) it('灾年 → 世界脉冲(tick 触发但有节奏)', () => { const w = World.create({ seed: 'fx-3', surname: '陆', familyName: '陆家', motto: 'm', difficulty: 'normal' }) const got = busOf(w) // 直接冒烟:任意 tick 不应抛错;特效只当事件发生才发 for (let i = 0; i < 12; i++) w.advanceMonth() expect(got.filter((k) => k === 'pulse').length).toBeGreaterThanOrEqual(0) }) })