新增测试矩阵(12 文件 / 161 cases): - rng 12 / data 18 / pcgen+cultivation 20 / economy 12 / combat+missions 24 - marriage+diplomacy 13 / events 12 / world+lifecycle 8(含镜像一致)/ save 4+5 / audit 8 审计带出并修复的真实缺陷: 1. Rng.pick 空数组未报错(防空白数组进而崩溃难查) 2. combatPowerOf 未应用功法悟道品阶战力加成(0.1.2 设计缺口) 3. 重伤者即使不代表伤状态仍按满速修炼(health 进修炼公式) 4. 寡妇/鳏夫无法再婚:候选列表放着人执行层却拒婚(spouseId 死旧契约) 5. isWidowed 参数契约陷阱:传 id 静默 false(升级接受 Character|Id 双签名)
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import { World } from '../world'
|
||
import { npcById } from '../../data/npcs'
|
||
import { findEvent, fire } from './events'
|
||
|
||
export function diplomacyTick(w: World): void {
|
||
const s = w.state
|
||
const drift = w.rng.chance(0.15)
|
||
for (const npc of Object.values(s.npcFamilies)) {
|
||
if (drift) {
|
||
if (npc.relation > 0) npc.relation -= 1
|
||
else if (npc.relation < 0) npc.relation += 1
|
||
}
|
||
if (npc.relation < -50) {
|
||
const last = (w.state.family.flag[`raidCD-${npc.id}`] as number | undefined) ?? 0
|
||
if (s.year - last >= 2 && w.rng.chance(0.03)) {
|
||
fire(w, `ev-raid-${npc.id}`)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
export function yearGrowth(w: World): void {
|
||
const s = w.state
|
||
for (const npc of Object.values(s.npcFamilies)) {
|
||
const def = npcById(npc.id)
|
||
const [a, b] = def.powerGrowth
|
||
npc.power += w.rng.int(a, b)
|
||
}
|
||
}
|
||
|
||
export function npcRelation(w: World, npcId: string): number {
|
||
return w.state.npcFamilies[npcId]?.relation ?? 0
|
||
}
|
||
|
||
export function giftNpc(w: World, npcId: string, stones: number): boolean {
|
||
const fam = w.state.family
|
||
if (stones <= 0 || fam.stones < stones) return false
|
||
fam.stones -= stones
|
||
const npc = w.state.npcFamilies[npcId]
|
||
const gain = Math.max(1, Math.round(stones / 12))
|
||
npc.relation = Math.min(100, npc.relation + gain)
|
||
w.log('info', `厚礼送往${npc.name},两家关系 +${gain}。`)
|
||
return true
|
||
}
|
||
|
||
export function makePeace(w: World, npcId: string): boolean {
|
||
const fam = w.state.family
|
||
const npc = w.state.npcFamilies[npcId]
|
||
if (fam.stones < 200) return false
|
||
fam.stones -= 200
|
||
npc.relation = Math.max(npc.relation + 35, 30)
|
||
w.chronicle('diplomacy', `${npc.name}立下和约,两家罢兵互市。`, undefined, true)
|
||
w.log('good', `与${npc.name}言和。`)
|
||
return true
|
||
}
|
||
|
||
export function marryNpcFamily(w: World, npcId: string): boolean {
|
||
const s = w.state
|
||
const fam = s.family
|
||
const npc = s.npcFamilies[npcId]
|
||
if (!npc || npc.relation < 25 || npc.allied) return false
|
||
const eligible = w
|
||
.aliveMembers()
|
||
.filter((c) => w.ageOf(c) >= 16 && w.ageOf(c) <= 46 && c.state !== 'expedition')
|
||
.filter((c) => !c.spouseId || w.isWidowed(c))
|
||
if (eligible.length === 0) return false
|
||
const npcDef = npcById(npcId)
|
||
const candidate = w.rng.pick(eligible)
|
||
candidate.spouseHouse = npc.name
|
||
npc.relation += 20
|
||
npc.allied = true
|
||
npc.alliedSinceYear = s.year
|
||
fam.reputation += 4
|
||
w.chronicle('marriage', `${candidate.name}与${npc.name}联姻,两家绸缪通好。`, candidate.id, true)
|
||
w.log('good', `${candidate.name} 与${npc.name}联姻成功!每年或降麟儿。`)
|
||
return true
|
||
}
|
||
|
||
export function arrangeWedding(w: World, aId: string, bId: string): boolean {
|
||
const a = w.memberById(aId)
|
||
const b = w.memberById(bId)
|
||
if (!a.alive || !b.alive) return false
|
||
if (a.spouseId && !w.isWidowed(a)) return false
|
||
if (b.spouseId && !w.isWidowed(b)) return false
|
||
if (a.gender === b.gender) return false
|
||
if (a.fatherId === b.fatherId && a.fatherId) return false
|
||
if (a.motherId === b.motherId && a.motherId) return false
|
||
a.spouseId = b.id
|
||
b.spouseId = a.id
|
||
const aAge = w.ageOf(a)
|
||
const bAge = w.ageOf(b)
|
||
if (w.state.family.flag['tenants']) {
|
||
w.state.family.reputation += 1
|
||
}
|
||
w.chronicle('marriage', `${a.name}(${aAge})与${b.name}(${bAge})拜堂成亲。`, a.id, true)
|
||
w.log('good', `${a.name} 与 ${b.name} 结为连理。`)
|
||
return true
|
||
}
|