v0.1.3: 深度审计修复(兼容/血缘/联姻/远征/数值)

- 旧档兼容:<0.1.1 存档缺 finance/yearStats/yearlyReports 字段加载归一化(防运行期崩溃)
- 血缘防护:同母异父兄妹也禁止婚配(指婚/媒人/联姻三路齐封)
- 联姻修正:一家一姻亲(allied 锁),再娶再嫁不再无限刷;男儿娶亲也子孙来归
- 和约语义:议和强推关系至 +30(真停战),不再打完一场还是仇雠
- 远征收队:任务完成/召回自动释放队员闲居;重伤者当月离队疗伤、不足定员提前撤队(修复人员永久困远征/卡状态)
- 数值:婴儿夭折率 2%→0.8%;劫掠队强度 0.9→0.78;事件负资源钳制不为负灵石
- UI:丹药按钮显示持有并禁点;点将模式支持取消重选;设置页移除摆设项
- 新增 audit 套件:8 项(含 600 月长跑耐力)总测试 38→46 全绿
This commit is contained in:
2026-08-23 08:34:13 +08:00
parent fefbe1f1d7
commit f38669fa4a
14 changed files with 242 additions and 52 deletions
+27 -9
View File
@@ -79,16 +79,34 @@ export function EventModal() {
)}
<div className="modal-opts">
{pendingEventDef.options.map((o, i) => {
const isRaid = raidIdx === i
return (
<button key={i} className="opt-btn" onClick={() => choose(i)}>
{isRaid && squadPicking ? '出战!(点将已毕)' : o.label}
{isRaid && !squadPicking && <span className="hint"> · </span>}
{!isRaid && o.hint && <span className="hint">{o.hint}</span>}
{squadPicking ? (
<>
<button className="opt-btn" onClick={() => choose(raidIdx)}>
{squadSel.length}
<span className="hint"></span>
</button>
)
})}
<button
className="btn"
onClick={() => {
setSquadPicking(false)
setSquadSel([])
}}
>
</button>
</>
) : (
pendingEventDef.options.map((o, i) => {
const isRaid = raidIdx === i
return (
<button key={i} className="opt-btn" onClick={() => choose(i)}>
{o.label}
{isRaid && <span className="hint"> · </span>}
{!isRaid && o.hint && <span className="hint">{o.hint}</span>}
</button>
)
})
)}
</div>
</div>
</div>
+14 -4
View File
@@ -9,6 +9,10 @@ import { combatPowerOf } from '../../game/engine/systems/combat'
import { lifespanOf } from '../../game/engine/systems/lifecycle'
import { POSTS, POST_ORDER } from '../../game/data/posts'
function pillCount(s: GameState, id: string): number {
return s.family.inventory[id] ?? 0
}
function equipableItems(member: Character, s: GameState): string[] {
const inv = Object.keys(ARTIFACT_POWER).filter((ai) => (s.family.inventory[ai] ?? 0) > 0)
if (member.equipment && !inv.includes(member.equipment)) inv.push(member.equipment)
@@ -104,33 +108,39 @@ export function MemberModal({ member }: { member: Character }) {
<>
<button
className="btn btn-sm"
disabled={pillCount(s, 'pill-qiyuan') <= 0}
title={`聚气丹×${pillCount(s, 'pill-qiyuan')}`}
onClick={() => {
w.takePill(member.id, 'pill-qiyuan')
bump()
}}
>
({pillCount(s, 'pill-qiyuan')})
</button>
{member.realm.major !== 'mortal' && (
<button
className="btn btn-sm"
disabled={pillCount(s, 'pill-ningyuan') <= 0}
title={`凝元丹×${pillCount(s, 'pill-ningyuan')}`}
onClick={() => {
w.takePill(member.id, 'pill-ningyuan')
bump()
}}
>
({pillCount(s, 'pill-ningyuan')})
</button>
)}
{member.realmProgress >= 100 && member.realm.major !== 'mortal' && (
{member.realmProgress >= 70 && member.realm.major !== 'mortal' && (
<button
className="btn btn-sm"
disabled={pillCount(s, 'pill-pojing') <= 0}
title={`破境丹×${pillCount(s, 'pill-pojing')}`}
onClick={() => {
w.takePill(member.id, 'pill-pojing')
bump()
}}
>
({pillCount(s, 'pill-pojing')})
</button>
)}
</>