- 统一时轮 GameClock:七 phase 注册制(production/aging/cultivation/missions/ events/diplomacy/epilogue) + 年首三钩子(婚配→岁贡→族簿);advanceMonth 化作薄壳; 新增系统只注册不改本体;alive 守卫、随机序、族簿时序均与重构前逐一等价 - 金钟罩:3 枚 seed × 560 月指纹常驻(重构前后已验证同哈希;时节属有意变更后重固化) - 统一随机 RngHub:开局播种(crypto UV)、音效白噪独立流、引擎 rng 带 nextCount 审计; 全工程拔除逻辑侧 Math.random - 时节系统:春夏秋冬乘子(春田+10%/夏修+5%/秋市+5%/冬闭+8%)入生产与修炼 - 崩溃保护:advance 异常自动存『出险前』档 + 停速提示回档 - 性能预算:dev-only 单 tick>60ms 报最慢 phase - 横轴年表:十年一格大事/生殇聚合 + 春秋原年轴视图 - 测试 197→225(时钟/收集器/四季/年轴/效果全矩阵/死局链/残留防御)
49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
import type { 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.008)
|
||
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)
|
||
}
|
||
}
|
||
}
|