v0.1.19: 八方风雨 + 孤立系统归并(双主线,1002 全绿)
【主线一:世界自演进深化《八方风雨》】 - NPC 战略姿态 stance:守成/扩张/隐忍/结盟四态,年首评估(era>景气>power>relation) 全行为调制:raid 概率×2/×0.4/×0、互攻阈值 -40/-70/不攻、贸量 ×1.3/×0.7、 赠礼收益 ally×1.3、结盟门槛 ally 放宽至30——NPC 从统计物理到行为战略 - 超卖潮(谷贱伤农):池>1.8×base 世界产能回调×0.7 + 年度播报(防玩家玩崩市场) - 盟约连坐:结盟令世仇(rel<-50)对玩家-20;盟者世仇 raid 概率×2 - 盟友求援:互攻失利盟友告急(distress 旗标)——WorldPanel 响应(出资200/见死不救) - 干预天下:调停(50灵石令世仇-60→-25、声望+2)/ 资助盟友;恩怨网情报视图(各家关系展开+调停钮) 【主线二:孤立系统归并引擎】 - P0 兜底修复:empty() 收敛 makeWorldSimState 单源 + normalize 补 tideTicks/calamityLeft/ era/eraStartYear/prosperity/distress/overfluxYear(旧档 NaN 级联防死) - FxGate 从 engine/kernel/fxqueue.ts 并入 ui/fx.ts(kernel 清纯引擎;deltas 顶层导出, 3 处引用 10 行改动);engine 侧零 UI 依赖再下一城 - 音效语义补充:onFx→blade/pulse/spark→sWar/sGong/sBell;onLog kind 兜底保留(不静音) - store.advance drift/season 段左移 fx.ts(fxSeason 复活接管 season 检测) - 死码清除:timesense.tideOf/tintLabel、tideDir 全链(类型/初始/写入/domain) - domain.ts worldSim 局部类型补全 0.1.18/0.1.19 全部新字段(断言类型安全) 【测试】1002 全绿(41 套件):stance-world 7 例(兜底/姿态/raid/超卖/连坐/调停/求援)
This commit is contained in:
@@ -65,6 +65,31 @@ export default function WorldPanel() {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{ws.distress && w.state.npcFamilies[ws.distress.id] && (
|
||||
<div className="ch-item" style={{ padding: '7px 10px', marginBottom: 10, border: '1px solid rgba(160,60,40,0.5)' }}>
|
||||
<span className="bad">⚠</span> 盟友 <b>{w.state.npcFamilies[ws.distress.id].name}</b> 遣使求援:
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
disabled={w.state.family.stones < 200}
|
||||
title={w.state.family.stones < 200 ? '灵石不足(需200)' : '捐 200 灵石助其重整武备'}
|
||||
onClick={() => { w.assistAlly(ws.distress!.id); bump() }}
|
||||
>出资200</button>
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
style={{ marginLeft: 6 }}
|
||||
title="置之不理(盟谊受损)"
|
||||
onClick={() => {
|
||||
const npc = w.state.npcFamilies[ws.distress!.id]
|
||||
if (npc) npc.relation = Math.max(0, npc.relation - 10)
|
||||
ws.distress = undefined
|
||||
w.log('info', `${npc?.name ?? '盟友'} 见吾族坐视,失望而返。`)
|
||||
bump()
|
||||
}}
|
||||
>见死不救</button>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{annals.length > 0 && (
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<h4 className="dim" style={{ margin: '4px 0 6px' }}>史官十年鉴</h4>
|
||||
@@ -155,6 +180,28 @@ export default function WorldPanel() {
|
||||
<div className="dim">宗主:{dyn?.leaderName ?? '未知'}({dyn ? MAJOR_NAMES[REALM_IDX[dyn.leaderRealmIdx] ?? 'qi'] : ''} · {dyn?.leaderAge ?? '?'}岁)</div>
|
||||
<div className="dim2" style={{ margin: '2px 0 6px' }}>{def.desc}</div>
|
||||
<div className="dim">新近之事:{dyn?.lastEvent ? `${dyn.lastEvent}(${dyn.lastEventYear ?? '?'}年)` : '暂无'}</div>
|
||||
<div style={{ marginTop: 4 }}>
|
||||
<div className="dim2" style={{ marginBottom: 3 }}>恩怨网(此家眼中各家)</div>
|
||||
{Object.entries((dyn as { relationsWithOthers?: Record<string, number> })?.relationsWithOthers ?? {}).map(([oid, rel]) => {
|
||||
const od = w.state.npcFamilies[oid]
|
||||
return od ? (
|
||||
<div key={oid} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '0.8rem', margin: '2px 0' }}>
|
||||
<span className="dim">{od.name}</span>
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
<span className={rel < -50 ? 'bad' : rel > 50 ? 'good' : 'dim'}>{rel}</span>
|
||||
{rel < -50 && (
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
disabled={w.state.family.stones < 50}
|
||||
title="耗 50 灵石劝和两家"
|
||||
onClick={() => { w.mediateNpcs(npc.id, oid); bump() }}
|
||||
>调停</button>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
) : null
|
||||
})}
|
||||
</div>
|
||||
{npc.alliedSinceYear && <div className="dim">同盟自 {npc.alliedSinceYear} 年</div>}
|
||||
<div style={{ marginTop: 6, display: 'flex', gap: 6 }}>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user