import { useGameStore } from '../store' import { useMemo } from 'react' import { npcById } from '../../game/data/npcs' import { MAJOR_NAMES } from '../../game/data/realms' import type { WorldSimState } from '../../game/engine/sim/worldsim-data' import { POOL_BASE, WORLDSIM, ERA_CONF } from '../../game/engine/sim/worldsim-data' import { combatPowerOf } from '../../game/engine/runtime/Systems/combat' import { sellItem, buyItem, marketPrice } from '../../game/engine/sim/Market' import { useState } from 'react' const RES_LABEL: Record = { lingcao: '灵草', lingkuang: '灵矿', beastcore: '兽核' } const REALM_IDX = ['mortal', 'qi', 'foundation', 'core', 'nascent', 'spirit'] as const export default function WorldPanel() { const world = useGameStore((s) => s.world) const bump = useGameStore((s) => s.bump) const revision = useGameStore((s) => s.revision) void revision const [view, setView] = useState(null) if (!world) return null const w = world const ws = w.state.worldSim as WorldSimState | undefined if (!ws) return
天机未显……(世界演化尚未展开)
const tide = ws.tide ?? 0.5 const tideLabel = tide > 0.9 ? '灵涨' : tide < 0.7 ? '灵衰' : '汐平' const pool = ws.marketPool ?? {} // P0-6 修复:newsFeed 恒定 120 时 length 依赖 memo 永冻结——直接每次 reverse(120 项零成本) const news = [...(ws.newsFeed ?? [])].slice().reverse() const calamity = ws.calamity const calamityLeft = ws.calamityLeft ?? 0 const myPower = Object.values(w.state.members) .filter((c) => c.alive) .reduce((a, c) => a + combatPowerOf(w, c), 0) const allPowers = Object.entries(w.state.npcFamilies).map(([id, n]) => ({ id, name: n.name, power: n.power })) const myRank = allPowers.filter((x) => x.power > myPower).length + 1 void myPower const eraName = ws.era ? ERA_CONF[ws.era].name : '平世' const eraDesc = ws.era ? ERA_CONF[ws.era].desc : '' const annals = news.filter((r) => r.kind === 'annal').slice(0, 3) const maxPower = Math.max(myPower, ...allPowers.map((x) => x.power)) || 1 return (
天下时局尽览:行市起落、宗主更替、灾年吉凶——皆随世界自演化而来。 结盟后岁差不降,每年另有盟利奉上(需关系≥40)。
【{eraName}】 灵潮 {tideLabel}({Math.round(tide * 100)}%) {calamity ? 灾年·{calamity}(约{calamityLeft}月后散去) : 风调雨顺} 本族雄基 {myRank}/{Object.keys(w.state.npcFamilies).length + 1} {Object.entries(pool).map(([k, v]) => { const base = POOL_BASE[k as keyof typeof POOL_BASE] ?? 100 const r = ((v as number) / base) * 100 const cls = r > 115 ? 'bad' : r < WORLDSIM.tradeFloorPct * 100 ? 'good' : 'dim' const dir = r > 105 ? '↑' : r < 95 ? '↓' : '→' return ( {RES_LABEL[k] ?? k}{dir}{Math.round(r)}% ) })}
{ws.distress && w.state.npcFamilies[ws.distress.id] && (
盟友 {w.state.npcFamilies[ws.distress.id].name} 遣使求援:
)} {annals.length > 0 && (

史官十年鉴

{annals.map((r, i) => (
{r.year}年{r.text}
))}
)}

群雄势衡(本族 vs 四方)

{[{ name: '我族', power: myPower, me: true }, ...allPowers.map((x) => ({ ...x, me: false }))].map((x) => (
{x.name}
{Math.round(x.power)}{x.power < 45 && !x.me ? '·衰' : ''}
))}

天下快讯

{news.length === 0 &&
风平浪静,尚无消息。
} {news.map((row, i) => { const canBuy = row.kind === 'quote' && row.itemId && w.state.family.stones >= marketPrice(w, row.itemId) * 5 const canSell = row.kind === 'quote' && row.itemId && (w.state.family.inventory[row.itemId] ?? 0) >= 5 const isCrisis = row.kind === 'calamity' return (
{row.year}年{row.month}月 {row.text} {isCrisis && w.state.family.stones >= 50 && ( )} {canBuy && ( )} {canSell && !canBuy && ( )}
) })}

群雄谱(点开宗主详情)

{Object.values(w.state.npcFamilies).map((npc) => { const def = npcById(npc.id) if (!def) return null const dyn = (ws.npcDyn ?? {})[npc.id] const open = view === npc.id return (
setView(open ? null : npc.id)}> {npc.name} {def.style} {npc.allied && } 势力{npc.power} · 关系{npc.relation}{' '} {dyn ? 景{dyn.prosperity} : null} {(dyn?.declineYears ?? 0) > 0 ? 衰{dyn.declineYears}/8 : null}
{open && (
宗主:{dyn?.leaderName ?? '未知'}({dyn ? MAJOR_NAMES[REALM_IDX[dyn.leaderRealmIdx] ?? 'qi'] : ''} · {dyn?.leaderAge ?? '?'}岁)
{def.desc}
新近之事:{dyn?.lastEvent ? `${dyn.lastEvent}(${dyn.lastEventYear ?? '?'}年)` : '暂无'}
恩怨网(此家眼中各家)
{Object.entries((dyn as { relationsWithOthers?: Record })?.relationsWithOthers ?? {}).map(([oid, rel]) => { const od = w.state.npcFamilies[oid] return od ? (
{od.name} 50 ? 'good' : 'dim'}>{rel} {rel < -50 && ( )}
) : null })}
{npc.alliedSinceYear &&
同盟自 {npc.alliedSinceYear} 年
}
{npc.allied && ( )}
)}
) })}
) }