"use client"; // 回响星核 / Echo Nexus — 星潮事件 UI(横幅 + 通知 + 背景叠层) import { useEffect, useState } from "react"; import { useGameStore } from "@/store/gameStore"; import { useToast } from "@/hooks/use-toast"; import { sfx } from "@/hooks/useAudio"; import { TIDE_EVENTS, TIDE_CONFIG } from "@/lib/game/starTide"; /** 星潮事件通知消费者:监听 _tideEvents 队列,弹 Toast + 播音效 */ export function StarTideNotifier() { const events = useGameStore((s) => s._tideEvents); const consume = useGameStore((s) => s.consumeTideEvents); const { toast } = useToast(); useEffect(() => { if (events.length === 0) return; const items = consume(); for (const ev of items) { if (ev.started) { const meta = TIDE_EVENTS[ev.started]; sfx("tideStart"); toast({ title: `${meta.icon} 星潮降临:${meta.name}`, description: meta.desc, }); } if (ev.ended) { const meta = TIDE_EVENTS[ev.ended]; if (ev.silenceCompensation && ev.silenceCompensation > 0) { sfx("techBuy"); toast({ title: `${meta.icon} 寂静期消散`, description: `虚空回赠 ${ev.silenceCompensation} 洞见。`, }); } else { sfx("tideEnd"); toast({ title: `${meta.icon} ${meta.name}结束`, description: "星潮退去,物理法则恢复。", }); } } } }, [events, consume, toast]); return null; } /** 顶部星潮指示器(活跃时显示倒计时芯片) */ export function StarTideIndicator() { const activeTide = useGameStore((s) => s.activeTide); const [, force] = useState(0); // 每秒刷新倒计时 useEffect(() => { if (!activeTide) return; const id = setInterval(() => force((n) => n + 1), 500); return () => clearInterval(id); }, [activeTide]); if (!activeTide) return null; const meta = TIDE_EVENTS[activeTide.type]; const remaining = Math.max(0, activeTide.endsAt - Date.now()); const secs = Math.ceil(remaining / 1000); const progress = 1 - remaining / TIDE_CONFIG.duration; return (