v0.1.19: 八方风雨 + 孤立系统归并(双主线,1002 全绿)
【主线一:世界自演进深化《八方风雨》】 - NPC 战略姿态 stance:守成/扩张/隐忍/结盟四态,年首评估(era>景气>power>relation) 全行为调制:raid 概率×2/×0.4/×0、互攻阈值 -40/-70/不攻、贸量 ×1.3/×0.7、 赠礼收益 ally×1.3、结盟门槛 ally 放宽至30——NPC 从统计物理到行为战略 - 超卖潮(谷贱伤农):池>1.8×base 世界产能回调×0.7 + 年度播报(防玩家玩崩市场) - 盟约连坐:结盟令世仇(rel<-50)对玩家-20;盟者世仇 raid 概率×2 - 盟友求援:互攻失利盟友告急(distress 旗标)——WorldPanel 响应(出资200/见死不救) - 干预天下:调停(50灵石令世仇-60→-25、声望+2)/ 资助盟友;恩怨网情报视图(各家关系展开+调停钮) 【主线二:孤立系统归并引擎】 - P0 兜底修复:empty() 收敛 makeWorldSimState 单源 + normalize 补 tideTicks/calamityLeft/ era/eraStartYear/prosperity/distress/overfluxYear(旧档 NaN 级联防死) - FxGate 从 engine/kernel/fxqueue.ts 并入 ui/fx.ts(kernel 清纯引擎;deltas 顶层导出, 3 处引用 10 行改动);engine 侧零 UI 依赖再下一城 - 音效语义补充:onFx→blade/pulse/spark→sWar/sGong/sBell;onLog kind 兜底保留(不静音) - store.advance drift/season 段左移 fx.ts(fxSeason 复活接管 season 检测) - 死码清除:timesense.tideOf/tintLabel、tideDir 全链(类型/初始/写入/domain) - domain.ts worldSim 局部类型补全 0.1.18/0.1.19 全部新字段(断言类型安全) 【测试】1002 全绿(41 套件):stance-world 7 例(兜底/姿态/raid/超卖/连坐/调停/求援)
This commit is contained in:
@@ -89,6 +89,18 @@ export function normalizeGameState(state: GameState): GameState {
|
||||
state.worldSim.secretQi = state.worldSim.secretQi ?? {}
|
||||
state.worldSim.newsFeed = state.worldSim.newsFeed ?? []
|
||||
if (typeof state.worldSim.tide !== 'number') state.worldSim.tide = 0.5
|
||||
if (typeof state.worldSim.tideTicks !== 'number') state.worldSim.tideTicks = 0
|
||||
if (typeof state.worldSim.npcSuccessions !== 'number') state.worldSim.npcSuccessions = 0
|
||||
if (typeof state.worldSim.calamityLeft !== 'number') state.worldSim.calamityLeft = 0
|
||||
if (state.worldSim.era !== 'shengshi' && state.worldSim.era !== 'pingshi' && state.worldSim.era !== 'luanshi' && state.worldSim.era !== 'mofa') {
|
||||
state.worldSim.era = 'pingshi'
|
||||
state.worldSim.eraStartYear = 1
|
||||
}
|
||||
for (const dyn of Object.values(state.worldSim.npcDyn)) {
|
||||
if (dyn && typeof (dyn as { prosperity?: unknown }).prosperity !== 'number') {
|
||||
(dyn as { prosperity: number }).prosperity = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state.family.headId && !state.members[state.family.headId]) {
|
||||
const firstAlive = Object.values(state.members).find((c) => c.alive)
|
||||
@@ -451,11 +463,47 @@ export class World {
|
||||
|
||||
// ==================== player actions ====================
|
||||
|
||||
/** 盟友求援响应:捐灵石助其重整武备(power+15、关系+8) */
|
||||
assistAlly(npcId: string, cost = 200): boolean {
|
||||
const fam = this.state.family
|
||||
const ws = this.state.worldSim as { distress?: { id: string } } | undefined
|
||||
if (!ws?.distress || ws.distress.id !== npcId) return false
|
||||
if (fam.stones < cost) return false
|
||||
fam.stones -= cost
|
||||
const npc = this.state.npcFamilies[npcId]
|
||||
if (!npc) return false
|
||||
npc.power = Math.min(900, npc.power + 15)
|
||||
npc.relation = Math.min(100, npc.relation + 8)
|
||||
fam.reputation += 3
|
||||
ws.distress = undefined
|
||||
this.log('good', `驰援${npc.name}——敌锋既退,盟谊愈坚(声望+3)。`)
|
||||
this.chronicle('diplomacy', `助${npc.name}重整武备,同盟益固。`, undefined, true)
|
||||
return true
|
||||
}
|
||||
|
||||
/** 调停战端:耗灵石五十,令两家罢兵三年(关系回暖至可容忍线) */
|
||||
mediateNpcs(npcA: string, npcB: string, cost = 50): boolean {
|
||||
const fam = this.state.family
|
||||
const dyns = this.state.worldSim?.npcDyn as Record<string, { relationsWithOthers: Record<string, number> }> | undefined
|
||||
if (!dyns?.[npcA]?.relationsWithOthers || dyns[npcA].relationsWithOthers[npcB] === undefined) return false
|
||||
if (fam.stones < cost) return false
|
||||
fam.stones -= cost
|
||||
for (const [a, b] of [[npcA, npcB], [npcB, npcA]] as const) {
|
||||
const rel = dyns[a].relationsWithOthers[b]
|
||||
if (rel < -30) dyns[a].relationsWithOthers[b] = -25
|
||||
}
|
||||
fam.reputation += 2
|
||||
this.log('info', `调停${this.state.npcFamilies[npcA]?.name ?? npcA}与${this.state.npcFamilies[npcB]?.name ?? npcB}——干戈化玉帛,声望+2。`)
|
||||
return true
|
||||
}
|
||||
|
||||
setAlliance(npcId: string, on: boolean): boolean {
|
||||
const npc = this.state.npcFamilies[npcId]
|
||||
if (!npc) return false
|
||||
if (on) {
|
||||
if (npc.relation < 40) return false
|
||||
const stA = (this.state.worldSim?.npcDyn?.[npcId] as { stance?: string } | undefined)?.stance
|
||||
const need = stA === 'ally' ? 30 : 40
|
||||
if (npc.relation < need) return false
|
||||
npc.allied = true
|
||||
npc.alliedSinceYear = this.state.year
|
||||
npc.power = Math.min(900, npc.power + 10)
|
||||
@@ -465,6 +513,19 @@ export class World {
|
||||
dyn.relationsWithOthers[npcId] = Math.max(-100, (dyn.relationsWithOthers[npcId] ?? 0) - 3)
|
||||
}
|
||||
}
|
||||
// 0.1.19 盟约连坐:其世仇恼我结盟,两邦关系走冷
|
||||
const dyn = (this.state.worldSim?.npcDyn as Record<string, { relationsWithOthers: Record<string, number> }> | undefined)?.[npcId]
|
||||
if (dyn) {
|
||||
for (const [oid, rel] of Object.entries(dyn.relationsWithOthers)) {
|
||||
if (rel < -50) {
|
||||
const foeNpc = this.state.npcFamilies[oid]
|
||||
if (foeNpc) {
|
||||
foeNpc.relation = Math.max(-100, foeNpc.relation - 20)
|
||||
this.log('info', `${foeNpc.name} 见我已与${npc.name}结盟,心怀芥蒂,关系-20。`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.log('good', `与${npc.name}结成同盟——盟誓既立,互不犯边。`)
|
||||
this.chronicle('diplomacy', `本族与${npc.name}缔结同盟。`, undefined, true)
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user