v0.1.2: 宗族气韵(职事/悟道/谱系/碑录/庆典/飞升/音效)

- 职事任命:长老(+修炼)/供奉(+战力)/执事(+坊市)/掌教(+闭关) 每人加成叠加,上限管理
- 功法悟道:修习积悟性点,小成/大成逐级+战力,大境界突破传道于直系晚辈
- 宗族谱系页:世代分带 + 夫妻同卷 + 子孙连枝,点节点开详情,先人簿可查
- 功德碑:宗主辞世即勒石,宗祠页碑录永存
- 百年庆典 + 飞升之路事件链(留世坐镇/仙风入体 或 云游飞升/宗族蒙荫)
- 合成音效(WebAudio):鼓点/钟鸣/纸韵/磬响,设置页开关
- 单测 29→38;typecheck/build 通过;GUI 冒烟受限于 WSLg 掉线(SMOKE-TIMEOUT 优雅退出)
This commit is contained in:
Hermes Agent
2026-08-23 08:28:49 +08:00
parent de491c997f
commit 839adc24a6
22 changed files with 864 additions and 8 deletions
@@ -7,6 +7,7 @@ import { TECHNIQUES } from '../../game/data/techniques'
import { ITEMS, ARTIFACT_POWER } from '../../game/data/items'
import { combatPowerOf } from '../../game/engine/systems/combat'
import { lifespanOf } from '../../game/engine/systems/lifecycle'
import { POSTS, POST_ORDER } from '../../game/data/posts'
function equipableItems(member: Character, s: GameState): string[] {
const inv = Object.keys(ARTIFACT_POWER).filter((ai) => (s.family.inventory[ai] ?? 0) > 0)
@@ -185,6 +186,42 @@ export function MemberModal({ member }: { member: Character }) {
</div>
)}
{member.alive && (
<div className="mm-sec">
<div className="dim" style={{ marginBottom: 6 }}></div>
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
<button
className={`btn btn-sm ${!member.post ? 'btn-primary' : ''}`}
onClick={() => {
w.assignPost(member.id, undefined)
bump()
}}
>
</button>
{POST_ORDER.filter((pid) => pid !== 'head').map((pid) => {
const def = POSTS[pid]
const maxed = w.postCount(pid) >= def.max && member.post !== pid
return (
<button
key={pid}
className={`btn btn-sm ${member.post === pid ? 'btn-primary' : ''}`}
disabled={maxed && !!member.post}
style={maxed && !member.post ? { opacity: 0.45 } : undefined}
title={`${def.desc}${w.postCount(pid)}/${def.max} 在任`}
onClick={() => {
w.assignPost(member.id, pid)
bump()
}}
>
{def.name}{w.postCount(pid)}/{def.max}
</button>
)
})}
</div>
</div>
)}
{member.alive && w.canMarry(member.id) && (
<div className="mm-sec">
<div className="dim" style={{ marginBottom: 6 }}></div>