v0.1.4: 百年定局(终局/大比/寄读/春秋原)
- 望气定鼎:stats 追踪四维(人兴/道兴/威名/香火)+ 十二称号分档 + 铭文诗 春秋原页预演称号,落印定局(青册留档,不阻继续游历) - 太虚大比:每五年征召,点将三关(初试/拔擢/问鼎)复用战斗结算, 名次四档红利(声望/灵石/全场好感),史书战报自动落笔 - 宗门寄读:随机宗门收徒(适龄少年),寄读 2-4 年期间每季寄资源, 期满三选:归来精进(可触发突破+随机机运)或续读深造;低概率择师不回 - 求经台:藏书阁≥3 解锁,两年一访得稀有功法 - 春秋原复盘页:气数四维图/岁末族簿汇编/生卒与突破年表/大比年表 - 修复:大比征召曾因月份条件错过整年;抢在百年庆典前的优先级倒置 - 测试 161→176(评分边界/称号分档/大比三轨/寄读全链/求经冷却)
This commit is contained in:
@@ -11,11 +11,11 @@ import { findInheritor } from '../creation'
|
||||
|
||||
const ALL_EVENTS: EventDef[] = [...EVENTS]
|
||||
|
||||
export function findEvent(id: string): EventDef | undefined {
|
||||
return ALL_EVENTS.find((e) => e.id === id) ?? dynamicEventFor(id)
|
||||
export function findEvent(id: string, world?: World): EventDef | undefined {
|
||||
return ALL_EVENTS.find((e) => e.id === id) ?? dynamicEventFor(id, world)
|
||||
}
|
||||
|
||||
export function dynamicEventFor(id: string): EventDef | undefined {
|
||||
export function dynamicEventFor(id: string, w?: World): EventDef | undefined {
|
||||
if (id.startsWith('ev-raid-')) {
|
||||
const npcId = id.replace('ev-raid-', '')
|
||||
const npc = npcById(npcId)
|
||||
@@ -47,6 +47,52 @@ export function dynamicEventFor(id: string): EventDef | undefined {
|
||||
]
|
||||
}
|
||||
}
|
||||
if (id.startsWith('ev-tournament-')) {
|
||||
const year = Number(id.replace('ev-tournament-', ''))
|
||||
return {
|
||||
id,
|
||||
name: '太虚大比',
|
||||
category: 'major',
|
||||
weight: 0,
|
||||
text: `太虚仙盟十年一会,新一期大比于祖庭开擂。观礼之众云集,百族竞锋——可遣嫡系赴赛,亦可称病让席。`,
|
||||
options: [
|
||||
{ label: '点将赴赛', hint: '战三关,位次定声望', eff: { tournament: true, flag: { [`tournamentYear-${year}`]: true } } },
|
||||
{ label: '献礼买名', hint: '灵石-200,名次垫底,各族好感略升', eff: { res: { stones: -200 }, relation: { 'n-xuanying': 5, 'n-danxin': 5, 'n-sihai': 5, 'n-nulei': 5 } } },
|
||||
{ label: '称病不出', hint: '声望小幅受挫', eff: { rep: -3 } }
|
||||
]
|
||||
}
|
||||
}
|
||||
if (id.startsWith('ev-apprentice-')) {
|
||||
const rest = id.replace('ev-apprentice-', '')
|
||||
const memberId = rest.split('-')[0]
|
||||
const member = w?.state.members[memberId] ?? undefined
|
||||
const sectName = member?.apprentice?.sect ?? '师门'
|
||||
const name = member?.name ?? '弟子'
|
||||
return {
|
||||
id,
|
||||
name: '寄读还乡',
|
||||
category: 'major',
|
||||
weight: 0,
|
||||
text: `${name} 在${sectName}寄读期满。宗门遣人传书:或归家,或续练。`,
|
||||
options: [
|
||||
{ label: '接其归家', hint: '其悟道大进,或携功法而归', eff: { flag: { apprenticeRet: memberId } } },
|
||||
{ label: '令其再拜师门', hint: '寄读二年,资源更厚', eff: { flag: { apprenticeStay: memberId } } }
|
||||
]
|
||||
}
|
||||
}
|
||||
if (id === 'ev-recruit') {
|
||||
return {
|
||||
id,
|
||||
name: '宗门收徒',
|
||||
category: 'major',
|
||||
weight: 0,
|
||||
text: '远方宗门遣师来访,观族中少年灵根不俗,欲收为记名弟子寄读。',
|
||||
options: [
|
||||
{ label: '送子寄读', hint: '其人外派,归时精进', eff: { apprentice: { build: true } } },
|
||||
{ label: '婉拒', hint: '无', eff: {} }
|
||||
]
|
||||
}
|
||||
}
|
||||
if (id === 'ev-feisheng') {
|
||||
return {
|
||||
id,
|
||||
@@ -64,6 +110,23 @@ export function dynamicEventFor(id: string): EventDef | undefined {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function asFlagString(flag: Record<string, number | boolean | string> | undefined, key: string): string | null {
|
||||
if (!flag) return null
|
||||
const v = flag[key]
|
||||
return typeof v === 'string' ? v : null
|
||||
}
|
||||
|
||||
import {
|
||||
runTournament as _runTournament,
|
||||
buildApprentice as _buildApprentice,
|
||||
finalizeApprentice as _finalizeApprentice,
|
||||
checkApprenticeExpiry,
|
||||
recruitCheck
|
||||
} from './tournament'
|
||||
export const runTournament = _runTournament
|
||||
export const buildApprentice = _buildApprentice
|
||||
export const finalizeApprentice = _finalizeApprentice
|
||||
|
||||
export function matchesCond(w: World, cond?: Cond): boolean {
|
||||
if (!cond) return true
|
||||
const s = w.state
|
||||
@@ -112,7 +175,7 @@ export function eventRoll(w: World): void {
|
||||
return
|
||||
}
|
||||
|
||||
// 里程碑检测(优先于日常事件)
|
||||
// 命运里程碑最优先(百年庆典 > 飞升之路)
|
||||
if (s.year >= 100 && !s.completedEvents.includes('ev-centennial')) {
|
||||
fire(w, 'ev-centennial')
|
||||
return
|
||||
@@ -122,6 +185,15 @@ export function eventRoll(w: World): void {
|
||||
fire(w, 'ev-feisheng')
|
||||
return
|
||||
}
|
||||
checkApprenticeExpiry(w)
|
||||
recruitCheck(w)
|
||||
|
||||
// 五年一会的太虚大比(该年任一时刻)
|
||||
const tourneyNext = Math.ceil(s.year / 5) * 5
|
||||
if (s.year >= 10 && s.year === tourneyNext && !s.completedEvents.includes(`ev-tournament-${tourneyNext}`)) {
|
||||
fire(w, `ev-tournament-${tourneyNext}`)
|
||||
return
|
||||
}
|
||||
|
||||
const roll = w.rng.next()
|
||||
const category: 'daily' | 'major' | 'fate' | undefined = roll < 0.5 ? 'daily' : roll < 0.78 ? 'major' : roll < 0.86 ? 'fate' : undefined
|
||||
@@ -151,7 +223,7 @@ export function fire(w: World, id: string): void {
|
||||
|
||||
export function applyEventChoice(w: World, eventId: string, optionIdx: number, squad?: string[]): void {
|
||||
const s = w.state
|
||||
const def = findEvent(eventId)
|
||||
const def = findEvent(eventId, w)
|
||||
if (!def) {
|
||||
s.pendingEvent = undefined
|
||||
return
|
||||
@@ -248,6 +320,22 @@ function applyEffect(w: World, eff: EffectDef, squad?: string[]): void {
|
||||
if (eff.addTech) {
|
||||
if (!fam.techniques.includes(eff.addTech)) fam.techniques.push(eff.addTech)
|
||||
}
|
||||
if (eff.tournament) {
|
||||
runTournament(w)
|
||||
}
|
||||
if (eff.apprentice?.build) {
|
||||
buildApprentice(w)
|
||||
}
|
||||
const retId = asFlagString(eff.flag, 'apprenticeRet')
|
||||
const stayId = asFlagString(eff.flag, 'apprenticeStay')
|
||||
if (retId) {
|
||||
finalizeApprentice(w, retId, 'return')
|
||||
delete fam.flag['apprenticeRet']
|
||||
}
|
||||
if (stayId) {
|
||||
finalizeApprentice(w, stayId, 'stay')
|
||||
delete fam.flag['apprenticeStay']
|
||||
}
|
||||
if (eff.feisheng) {
|
||||
const s2 = w.state
|
||||
const immortal = w
|
||||
|
||||
Reference in New Issue
Block a user