v0.1.1: 养成闭环 + 管理自主 + 存档安全

- 指婚/续弦:成员详情可主动找人结亲(血亲自动排除、鳏寡可再醮)
- 装备 UI:法宝从府库装备/替换,战力实时反馈
- 御敌点将:劫掠事件可自选迎战阵容(默认 Top4 可改)
- 宗祠祭祖:每两年一次,灵石150 → 声望+6/全族修为小升
- 回档时间轴:每季快照列表,一键回卷(回卷前自动保当前档)
- 战报匣子:史书页全文战报留存可翻阅
- 年度族簿纸笺:每年初弹收支/人丁/战力简报
- 媒人提示条 + 寻衅一年冷却 + 出生率与劫掠频率微调
- 单测 19→29(storage mock roundtrip/回档/指婚血亲/祭祖/寻衅/装备/账本)
This commit is contained in:
2026-08-23 08:16:40 +08:00
parent 4bacbd432e
commit 6b15a97d0c
24 changed files with 734 additions and 26 deletions
+64
View File
@@ -89,3 +89,67 @@ describe('Event conditions', () => {
expect(matchesCondPub(w, { maxAdult: 2 })).toBe(false)
})
})
describe('Marriage & equipment & rites', () => {
it('rejects siblings, accepts strangers', () => {
const w = World.create({ seed: 'marry', surname: '王', familyName: '王家', motto: 'm', difficulty: 'normal' })
const bro = w.state.members['x3']
const sis = w.state.members['x5']
expect(w.canMarry(bro.id)).toBe(true)
expect(w.canMarry(sis.id)).toBe(true)
expect(w.marriageCandidatesOf(bro.id).map((c) => c.id)).not.toContain(sis.id)
})
it('widow can remarry via candidates', () => {
const w = World.create({ seed: 'remarry', surname: '赵', familyName: '赵家', motto: 'm', difficulty: 'normal' })
const wife = w.state.members['x2']
wife.spouseId = 'x1'
w.state.members['x1'].alive = false
expect(w.canMarry(wife.id)).toBe(true)
expect(w.marriageCandidatesOf(wife.id).length).toBeGreaterThan(0)
})
it('equipping artifact raises combat power', () => {
const w = World.create({ seed: 'equip', surname: '钱', familyName: '钱家', motto: 'm', difficulty: 'normal' })
const c = w.state.members['x4']
const power0 = combatPowerOf(w, c)
w.state.family.inventory['weapon-qi'] = 1
w.equip(c.id, 'weapon-qi')
expect(combatPowerOf(w, c)).toBeGreaterThan(power0)
})
it('ancestral rite costs, respects cooldown, grants boon', () => {
const w = World.create({ seed: 'rite', surname: '孙', familyName: '孙家', motto: 'm', difficulty: 'easy' })
const fam = w.state.family
fam.stones = 1000
const rep0 = fam.reputation
const head = w.state.members['x1']
head.realmProgress = 50
expect(w.ancestralRite()).toBe(true)
expect(fam.stones).toBe(850)
expect(fam.reputation).toBe(rep0 + 6)
expect(head.realmProgress).toBe(53)
expect(w.ancestralRite()).toBe(false)
})
it('taunt has 1-year cooldown', () => {
const w = World.create({ seed: 'taunt', surname: '周', familyName: '周家', motto: 'm', difficulty: 'normal' })
const npcId = 'n-nulei'
const before = w.state.npcFamilies[npcId].relation
expect(w.tauntNpc(npcId)).toBe(true)
expect(w.state.npcFamilies[npcId].relation).toBe(before - 20)
expect(w.tauntNpc(npcId)).toBe(false)
})
})
describe('Yearly report', () => {
it('generates a report per full year', () => {
const w = World.create({ seed: 'rep', surname: '吴', familyName: '吴家', motto: 'm', difficulty: 'normal' })
for (let i = 0; i < 14; i++) w.advanceMonth()
expect(w.state.yearlyReports.length).toBe(1)
const r = w.state.yearlyReports[0]
expect(r.year).toBe(1)
expect(r.nets).toBeGreaterThanOrEqual(0)
expect(r.power).toBeGreaterThan(0)
})
})