import { useGameStore } from '../store' import { useMemo, useState, memo } from 'react' const CAT_NAME: Record = { birth: '诞庆', marriage: '姻缘', death: '祭丧', breakthrough: '突破', battle: '战事', trade: '商贸', diplomacy: '外交', exploration: '寻宝', building: '营造', event: '奇遇', misc: '家常' } interface ChEntry { id: string year: number month: number category: string important: boolean text: string } function grouped(entries: ChEntry[]): { year: number; items: ChEntry[] }[] { const map = new Map() for (const e of entries) { const g = map.get(e.year) ?? [] g.push(e) map.set(e.year, g) } return [...map.entries()].sort((a, b) => b[0] - a[0]).map(([year, items]) => ({ year, items })) } function statOf(g: { items: { category: string }[] }): string { const births = g.items.filter((i) => i.category === 'birth').length const deaths = g.items.filter((i) => i.category === 'death').length const bt = g.items.filter((i) => i.category === 'breakthrough').length const parts: string[] = [] if (births) parts.push(`生${births}`) if (deaths) parts.push(`殇${deaths}`) if (bt) parts.push(`突破${bt}`) return parts.join(' · ') } export default function ChroniclePanel() { const world = useGameStore((s) => s.world) const revision = useGameStore((s) => s.revision) void revision const [filter, setFilter] = useState('all') const [battleId, setBattleId] = useState(null) const [draft, setDraft] = useState('') const entries = useMemo(() => { if (!world) return [] const all = [...world.state.chronicle] const filtered = filter === 'all' ? all : all.filter((e) => e.category === filter) return filtered.slice().sort((a, b) => (b.year - a.year) || (b.month - a.month)) }, [world, filter, world ? world.state.chronicle.length : 0]) if (!world) return null const battles = world.state.battles.slice().reverse() const battle = battles.find((b) => b.id === battleId) const groupedEntries = useMemo(() => grouped(entries), [entries]) return (
族史一卷:系统自动记下的家族大事,供族人题翰墨于旁。倒序排列,可回看任意一年的兴衰细节。
setDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && draft.trim()) { world.chronicle('misc', draft.trim(), undefined, false) setDraft('') } }} />
{Object.entries(CAT_NAME).map(([k, v]) => ( ))}
{groupedEntries.map((g) => (
{g.year}年 {g.items.length}条 · {statOf(g)}
{g.items.map((e) => (
{e.month}月 {CAT_NAME[e.category] ?? e.category} {e.text}
))}
))} {entries.length === 0 &&
暂无记载。
}
战报匣(全文留存)
{battle ? (
{battle.title} {battle.year}年{battle.month}月 ·{' '} {battle.winner === 'player' ? '我方得胜' : battle.winner === 'enemy' ? '我方败北' : '平分秋色'}
{battle.lines.slice(1).map((l, i) => (
· {l}
))} {battle.losses.length > 0 && (
我方折损:{battle.losses.join('、')}
)}
) : battles.length === 0 ? (
尚无战事可录。
) : (
{battles.map((b) => (
{b.year}年{b.month}月 {b.title} {b.winner === 'player' ? '胜' : b.winner === 'enemy' ? '负' : '平'}
))}
)}
) }