- 指婚/续弦:成员详情可主动找人结亲(血亲自动排除、鳏寡可再醮) - 装备 UI:法宝从府库装备/替换,战力实时反馈 - 御敌点将:劫掠事件可自选迎战阵容(默认 Top4 可改) - 宗祠祭祖:每两年一次,灵石150 → 声望+6/全族修为小升 - 回档时间轴:每季快照列表,一键回卷(回卷前自动保当前档) - 战报匣子:史书页全文战报留存可翻阅 - 年度族簿纸笺:每年初弹收支/人丁/战力简报 - 媒人提示条 + 寻衅一年冷却 + 出生率与劫掠频率微调 - 单测 19→29(storage mock roundtrip/回档/指婚血亲/祭祖/寻衅/装备/账本)
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
import { World } from '../world'
|
||
import { MAJORS } from '../../data/realms'
|
||
import { calcLifespan } from '../pcgen'
|
||
|
||
export function lifespanOf(w: World, c: { realm: { major: keyof typeof MAJORS }; physique: number }): number {
|
||
return calcLifespan(c.realm.major, c.physique)
|
||
}
|
||
|
||
export function deathTick(w: World): void {
|
||
for (const c of Object.values(w.state.members)) {
|
||
if (!c.alive) continue
|
||
const age = w.ageOf(c)
|
||
const span = lifespanOf(w, c)
|
||
const softCap = span * 0.85
|
||
let p = 0
|
||
if (age >= span) p = 0.35
|
||
else if (age >= softCap) {
|
||
const t = (age - softCap) / (span - softCap)
|
||
p = Math.min(0.3, Math.pow(t, 5) * 0.9)
|
||
}
|
||
if (c.health < 30) p += 0.18
|
||
if (age < 2) p = Math.max(p, 0.02)
|
||
if (p > 0 && w.rng.chance(p)) {
|
||
c.alive = false
|
||
c.deathYear = w.state.year
|
||
const cause = age < 2 ? '幼夭' : c.health < 30 ? '伤势不治' : '寿元将尽'
|
||
c.deathCause = cause
|
||
w.state.yearStats.deaths += 1
|
||
w.chronicle('death', `${c.name} 辞世,年 ${age}。${age < 2 ? '族人无不痛惜。' : c.health < 30 ? '临终前仍在牵挂家族。' : '族人焚香送别。'}`, c.id, true)
|
||
w.log('bad', `${c.name}(${age}岁)${cause}。`)
|
||
}
|
||
}
|
||
}
|
||
|
||
export function woundHealTick(w: World): void {
|
||
for (const c of Object.values(w.state.members)) {
|
||
if (!c.alive) continue
|
||
if (c.state === 'wounded') {
|
||
c.health = Math.min(100, c.health + 12 + c.physique)
|
||
if (c.health >= 95) {
|
||
c.state = 'idle'
|
||
w.log('info', `${c.name} 伤势痊愈。`)
|
||
}
|
||
} else if (c.health < 100) {
|
||
c.health = Math.min(100, c.health + 2 + c.physique * 0.5)
|
||
}
|
||
}
|
||
}
|