diff --git a/src/renderer/ui/panels/ChroniclePanel.tsx b/src/renderer/ui/panels/ChroniclePanel.tsx index 4271d39..14df8e0 100644 --- a/src/renderer/ui/panels/ChroniclePanel.tsx +++ b/src/renderer/ui/panels/ChroniclePanel.tsx @@ -1,5 +1,5 @@ import { useGameStore } from '../store' -import { useMemo, useState } from 'react' +import { useMemo, useState, memo } from 'react' const CAT_NAME: Record = { birth: '诞庆', @@ -61,6 +61,7 @@ export default function ChroniclePanel() { 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 (
@@ -99,7 +100,7 @@ export default function ChroniclePanel() { ))}
- {grouped(entries).map((g) => ( + {groupedEntries.map((g) => (
{g.year}年 {g.items.length}条 · {statOf(g)}
{g.items.map((e) => ( diff --git a/src/renderer/ui/panels/DiplomacyPanel.tsx b/src/renderer/ui/panels/DiplomacyPanel.tsx index 0d71269..eae5a0a 100644 --- a/src/renderer/ui/panels/DiplomacyPanel.tsx +++ b/src/renderer/ui/panels/DiplomacyPanel.tsx @@ -1,12 +1,89 @@ import { useGameStore } from '../store' import { npcById } from '../../game/data/npcs' import { giftNpc, makePeace, marryNpcFamily, calcGiftGain, GIFT_TIERS } from '../../game/engine/runtime/Systems/diplomacy' -import { useMemo } from 'react' +import { useMemo, memo } from 'react' import { MAJOR_NAMES } from '../../game/data/realms' +import type { World } from '../../game/engine/runtime/World' +import type { NpcFamilyState } from '../../game/types/domain' const REL_TYPE = (r: number) => r >= 80 ? ['死生之交', 'good'] : r >= 50 ? ['通好之势', 'good'] : r >= 25 ? ['友善', 'warn'] : r >= 10 ? ['温和', 'warn'] : r > -10 ? ['中立', ''] : r > -30 ? ['嫌隙', ''] : r > -50 ? ['敌对', 'bad'] : ['仇雠', 'bad'] +const NpcRow = memo(function NpcRow({ npc, world, bump }: { npc: NpcFamilyState; world: World; bump: () => void }) { + const def = npcById(npc.id) + if (!def) return null + const [relLabel, relCls] = REL_TYPE(npc.relation) + const married = npc.allied + return ( +
+
+
{npc.name}
+
{def.style} · {npc.region}
+
+
+
= 0 ? '#2e5a2e' : '#6e2f2f' }}> +
= 0 ? '#5a8a44' : '#8a4444' + }} + /> +
+
+ 关系{npc.relation} · {relLabel} · 势力{npc.power} +
+
+
+ {MAJOR_NAMES[def.leaderRealm]}宗主 +
+
+ {GIFT_TIERS.map((t) => ( + + ))} + + + + {npc.relation < -30 && ( + + )} +
+
+ ) +}) + export default function DiplomacyPanel() { const world = useGameStore((s) => s.world) const bump = useGameStore((s) => s.bump) @@ -23,80 +100,9 @@ export default function DiplomacyPanel() {
外交之道:送礼结好、联姻通好;仇恨过深的老对家会遣队劫掠。家族声望同样影响诸家态度。
- {sorted.map((npc) => { - const def = npcById(npc.id) - if (!def) return null - const [relLabel, relCls] = REL_TYPE(npc.relation) - const married = npc.allied - return ( -
-
-
{npc.name}
-
{def.style} · {npc.region}
-
-
-
= 0 ? '#2e5a2e' : '#6e2f2f' }}> -
= 0 ? '#5a8a44' : '#8a4444' - }} - /> -
-
- 关系{npc.relation} · {relLabel} · 势力{npc.power} -
-
-
- {MAJOR_NAMES[def.leaderRealm]}宗主 -
-
- {GIFT_TIERS.map((t) => ( - - ))} - - - - {npc.relation < -30 && ( - - )} -
-
- ) - })} + {sorted.map((npc) => ( + + ))}
示好请用灵石铺路;寻衅会立刻恶化关系,且可能招致劫掠或围庄。
diff --git a/src/renderer/ui/panels/WorldPanel.tsx b/src/renderer/ui/panels/WorldPanel.tsx index c37ee7f..e441a20 100644 --- a/src/renderer/ui/panels/WorldPanel.tsx +++ b/src/renderer/ui/panels/WorldPanel.tsx @@ -1,5 +1,5 @@ import { useGameStore } from '../store' -import { useMemo } from 'react' +import { useMemo, memo } from 'react' import { npcById } from '../../game/data/npcs' import { MAJOR_NAMES } from '../../game/data/realms' import type { WorldSimState } from '../../game/engine/sim/worldsim-data' @@ -7,10 +7,53 @@ import { POOL_BASE, WORLDSIM, ERA_CONF } from '../../game/engine/sim/worldsim-da import { combatPowerOf } from '../../game/engine/runtime/Systems/combat' import { sellItem, buyItem, marketPrice } from '../../game/engine/sim/Market' import { useState } from 'react' +import type { World } from '../../game/engine/runtime/World' const RES_LABEL: Record = { lingcao: '灵草', lingkuang: '灵矿', beastcore: '兽核' } const REALM_IDX = ['mortal', 'qi', 'foundation', 'core', 'nascent', 'spirit'] as const +/** 0.1.40 memo 化天下快讯——120 条 newsFeed 不随主面板其他状态变动重渲染 */ +const NewsList = memo(function NewsList({ news, world, bump }: { news: { year: number; month: number; src: string; text: string; itemId?: string; kind?: string }[]; world: World; bump: () => void }) { + return ( + <> + {news.length === 0 &&
风平浪静,尚无消息。
} + {news.map((row, i) => { + const canBuy = row.kind === 'quote' && row.itemId && world.state.family.stones >= marketPrice(world, row.itemId) * 5 + const canSell = row.kind === 'quote' && row.itemId && (world.state.family.inventory[row.itemId] ?? 0) >= 5 + const isCrisis = row.kind === 'calamity' + return ( +
+ {row.year}年{row.month}月 + {row.text} + {isCrisis && world.state.family.stones >= 50 && ( + + + + )} + {canBuy && ( + + + + )} + {canSell && !canBuy && ( + + + + )} +
+ ) + })} + + ) +}) + export default function WorldPanel() { const world = useGameStore((s) => s.world) const bump = useGameStore((s) => s.bump) @@ -123,40 +166,7 @@ export default function WorldPanel() {

天下快讯

- {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 && ( - - - - )} -
- ) - })} +