v0.1.0: 仙途家族志 · Chronicle of the Immortal Clan

家族模拟器首版:修仙/经营/战斗/外交/叙事全套系统
- Electron + React + TS + MetonaSqlark(aria+OPFS)
- 水墨中国风 UI
- 引擎种子随机、确定性可回放
- 19 项单元测试、端到端冒烟验证
This commit is contained in:
2026-08-23 00:04:16 +08:00
commit adb22f0558
69 changed files with 14305 additions and 0 deletions
+305
View File
@@ -0,0 +1,305 @@
export interface Cond {
all?: Cond[]
any?: Cond[]
not?: Cond
minYear?: number
minGeneration?: number
minHeadRealm?: string
minBuilding?: { id: string; level: number }
minRep?: number
maxRep?: number
minResource?: { id: string; n: number }
minAdult?: number
maxAdult?: number
minMembers?: number
eligibleAdult?: number
relation?: { npcId: string; gt?: number; lt?: number }
flag?: { key: string; eq: number | boolean | string }
hasMeditation?: boolean
noWarForYears?: number
minTechCount?: number
}
export interface MemberEffect {
by: 'exp' | 'wound' | 'heal' | 'breakthrough' | 'fatal' | 'repGain' | 'inspire' | 'loot' | 'madness' | 'genius'
target: 'random' | 'head' | 'youngest' | 'oldest' | 'highestPerception' | 'highestPower' | 'highestFortune' | 'all'
n?: number
desc?: string
}
export interface EffectDef {
res?: Record<string, number>
rep?: number
relation?: Record<string, number>
addBuilding?: string
memberBy?: MemberEffect
pillGain?: Record<string, number>
mission?: string
raid?: { npcId: string }
flag?: Record<string, number | boolean | string>
techniqueChance?: number
artifactChance?: number
addTech?: string
}
export interface EventOptionDef {
label: string
hint?: string
eff: EffectDef
note?: string
}
export interface EventDef {
id: string
name: string
category: 'daily' | 'major' | 'fate'
weight: number
once?: boolean
cond?: Cond
text: string
options: EventOptionDef[]
}
export function eventCategoryName(cat: EventDef['category']): string {
return cat === 'daily' ? '族中日常' : cat === 'major' ? '家国大事' : '乾坤造化'
}
export const EVENTS: EventDef[] = [
{
id: 'ev-youdao', name: '云游道人', category: 'daily', weight: 8,
text: '一名袖袍破旧的云游道人路过祖宅门前,自称识得丹药机巧,愿以一枚聚气丹换五斤灵草。',
options: [
{ label: '换!', hint: '灵草-5,聚气丹+1', eff: { res: { lingcao: -5 }, pillGain: { 'pill-qiyuan': 1 } } },
{ label: '送他些斋饭', hint: '灵石-10,声望+2', eff: { res: { stones: -10 }, rep: 2 } },
{ label: '赶走', hint: '无', eff: {} }
]
},
{
id: 'ev-chonghai', name: '灵田虫害', category: 'daily', weight: 8,
cond: { minBuilding: { id: 'lingtian', level: 1 } },
text: '成片的灵草被青翅虫啃食,照此下去今季收成不保。',
options: [
{ label: '请灵师除虫', hint: '灵石-60', eff: { res: { stones: -60 } } },
{ label: '亲自下田燃烧草', hint: '收成-40%', eff: { res: { lingcao: -8 } } },
{ label: '冷眼旁观', hint: '灵草-20', eff: { res: { lingcao: -20 } } }
]
},
{
id: 'ev-liumin', name: '流民投奔', category: 'daily', weight: 6,
cond: { minRep: 0 },
text: '乱世流民逃难至此,成群跪在庄外,望收留他们做佃户。',
options: [
{ label: '开仓设粥', hint: '灵石-40,声望+4', eff: { res: { stones: -40 }, rep: 4 } },
{ label: '遣散', hint: '声望-2', eff: { rep: -2 } },
{ label: '收为佃户', hint: '灵田产量长增', eff: { res: { stones: -30 }, rep: 2, flag: { tenants: true } } }
]
},
{
id: 'ev-takuang', name: '后山塌方', category: 'daily', weight: 6,
cond: { minBuilding: { id: 'lingkuang', level: 1 } },
text: '后山矿洞一段塌方,矿工数人被困,矿脉暂无人敢下。',
options: [
{ label: '出灵石救治', hint: '灵石-50', eff: { res: { stones: -50 } } },
{ label: '调族人救援', hint: '随机成员负伤', eff: { memberBy: { by: 'wound', target: 'random', n: 15 } } },
{ label: '封洞了事', hint: '矿脉-5', eff: { res: { lingkuang: -5 } } }
]
},
{
id: 'ev-lieshou', name: '猎户献兽', category: 'daily', weight: 5,
cond: { minRep: 10 },
text: '山中猎户捉得一头灵鹿,闻贵族历代尚灵,特来献上。',
options: [
{ label: '买下放生', hint: '灵石-20', eff: { res: { stones: -20 } } },
{ label: '收为坐骑', hint: '兽核+2', eff: { res: { beastcore: 2 } } },
{ label: '收他入庄', hint: '声望+1', eff: { rep: 1 } }
]
},
{
id: 'ev-jiangjiang', name: '巧匠上门', category: 'daily', weight: 5,
cond: { minResource: { id: 'stones', n: 20 } },
text: '一位独臂巧匠携着琳琅法器上门求售,说是祖传手笔。',
options: [
{ label: '买一件回头客', hint: '灵石-100,凡器+1', eff: { res: { stones: -100 }, pillGain: { 'weapon-fan': 1 } } },
{ label: '替他说媒去', hint: '声望+2', eff: { rep: 2 } },
{ label: '让他留个住址', hint: '无', eff: {} }
]
},
{
id: 'ev-lingyu', name: '灵雨', category: 'daily', weight: 6,
cond: { minBuilding: { id: 'lingtian', level: 1 } },
text: '一夜灵雨滂沱,田里的灵草吸饱了灵雨,长势惊人。',
options: [
{ label: '天佑我家!', hint: '灵草+60', eff: { res: { lingcao: 60 } } }
]
},
{
id: 'ev-yupei', name: '孩童拾玉', category: 'daily', weight: 5,
text: '族中孩童在后山拾到一枚玄玉,触手生温,似有不凡。',
options: [
{ label: '供奉宗祠', hint: '声望+5', eff: { rep: 5, flag: { jade: true } } },
{ label: '锁入库房', hint: '灵石+80', eff: { res: { stones: 80 } } },
{ label: '让孩童留之', hint: '其气运+2', eff: { memberBy: { by: 'loot', target: 'youngest', n: 2 }, flag: { jade2: true } } }
]
},
{
id: 'ev-shangdui', name: '路过商队', category: 'daily', weight: 6,
text: '一支四海王家的商队路过,问庄上可有灵矿出手,价给得公道。',
options: [
{ label: '出货', hint: '灵矿-15,灵石+240', eff: { res: { lingkuang: -15, stones: 240 } } },
{ label: '请他们留宿', hint: '声望+2', eff: { rep: 2 } },
{ label: '不理', hint: '无', eff: {} }
]
},
{
id: 'ev-zhusu', name: '祝氏家奴', category: 'daily', weight: 5,
cond: { relation: { npcId: 'n-nulei', lt: 20 } },
text: '捉住一个东丘祝氏的家奴,偷我庄上的灵草,被族人绑来听候发落。',
options: [
{ label: '重罚后放回', hint: '祝氏关系-8', eff: { relation: { 'n-nulei': -8 } } },
{ label: '送还祝氏', hint: '祝氏关系+6', eff: { relation: { 'n-nulei': 6 } } },
{ label: '就地正法', hint: '祝氏关系-20,声望+3', eff: { relation: { 'n-nulei': -20 }, rep: 3 } }
]
},
{
id: 'ev-lunda', name: '论道会', category: 'daily', weight: 5,
cond: { minAdult: 2 },
text: '方圆修士开论道会,族人收到请帖,座上皆是气息不凡之辈。',
options: [
{ label: '遣长老赴会', hint: '随机成员修为+15%', eff: { memberBy: { by: 'exp', target: 'highestPower', n: 15 } } },
{ label: '全族观礼', hint: '声望+3', eff: { rep: 3 } },
{ label: '婉拒', hint: '无', eff: {} }
]
},
{
id: 'ev-wenyi', name: '西川瘟疫', category: 'major', weight: 7,
cond: { minYear: 2 },
text: '西川爆发古怪瘟疫,卢氏求药无门,遣人来向庄上求助,愿以族传丹方相谢。',
options: [
{ label: '赠药救人', hint: '灵草-30,灵石-50,木氏关系+15', eff: { res: { lingcao: -30, stones: -50 }, relation: { 'n-danxin': 15 }, rep: 5 } },
{ label: '坐地起价', hint: '灵石+200,木氏关系-15', eff: { res: { stones: 200 }, relation: { 'n-danxin': -15 } } },
{ label: '关门避险', hint: '声望-2', eff: { rep: -2 } }
]
},
{
id: 'ev-qiuchee', name: '借剑之请', category: 'major', weight: 5,
cond: { minBuilding: { id: 'cangshu', level: 1 } },
text: '玄影沈氏遣使来借一部剑典,言按借期十年奉还,愿以两部法器为押。',
options: [
{ label: '借!', hint: '法器+1,沈氏关系+12', eff: { pillGain: { 'weapon-qi': 1 }, relation: { 'n-xuanying': 12 } } },
{ label: '婉拒', hint: '沈氏关系-5', eff: { relation: { 'n-xuanying': -5 } } },
{ label: '借,但要人质', hint: '沈氏关系+2,声望-2', eff: { relation: { 'n-xuanying': 2 }, rep: -2 } }
]
},
{
id: 'ev-xiamaozi', name: '神秘夜访', category: 'fate', weight: 4,
once: true,
text: '月黑风高,一位蒙面客深夜造访,自称知晓祖地深处有一处上古洞府,愿以两成收成易开启之诀。',
options: [
{ label: '与他交易', hint: '灵石-120', eff: { res: { stones: -120 }, flag: { caveClue: true }, rep: 2 } },
{ label: '绑了问话', hint: '可能招祸', eff: { flag: { caveRumor: true }, rep: -2 } },
{ label: '赏夜赶出', hint: '无', eff: {} }
]
},
{
id: 'ev-zuling', name: '祖祠异动', category: 'fate', weight: 3,
once: true,
cond: { minBuilding: { id: 'zongci', level: 2 } },
text: '深夜祖祠忽闻钟鸣,牌位前竟现一尊淡影,凝视良久,留下二字:「续裔」。',
options: [
{ label: '上香叩拜', hint: '声望+8,全族修炼+', eff: { rep: 8, memberBy: { by: 'inspire', target: 'all', n: 5 }, flag: { ancestorBless: true } } },
{ label: '祭以三牲', hint: '声望+12', eff: { rep: 12, flag: { ancestorBless: true } } },
{ label: '令人守夜', hint: '无', eff: {} }
]
},
{
id: 'ev-leize', name: '万兽潮', category: 'fate', weight: 3,
once: true,
cond: { minYear: 3 },
text: '数万妖兽从东畔雷泽奔涌而下,漫山遍野,直逼庄墙!须速决断。',
options: [
{ label: '举族死守', hint: '战斗!打赢得兽核与声望', eff: { raid: { npcId: 'n-nulei' }, flag: { beastTide: true } } },
{ label: '迁建宗祠', hint: '声望-6,灵石-100', eff: { res: { stones: -100 }, rep: -6 } },
{ label: '联姻求救', hint: '灵石-80,木氏关系+8', eff: { res: { stones: -80 }, relation: { 'n-danxin': 8 } } }
]
},
{
id: 'ev-jobai', name: '卖女求荣', category: 'major', weight: 4,
cond: { minAdult: 1, maxAdult: 8 },
text: '有媒人上门,说东丘祝氏大公子瞧上族中一位姑娘,愿出三百灵石聘礼换两家结好。',
options: [
{ label: '应下这门亲', hint: '灵石+300,祝氏关系+10', eff: { res: { stones: 300 }, relation: { 'n-nulei': 10 } } },
{ label: '再加价', hint: '灵石+450,祝氏关系-5', eff: { res: { stones: 450 }, relation: { 'n-nulei': -5 } } },
{ label: '回绝', hint: '无', eff: {} }
]
},
{
id: 'ev-lingshou', name: '灵兽认主', category: 'major', weight: 4,
cond: { minBuilding: { id: 'lingshou', level: 2 } },
text: '园中一只幼兽七日不食,气若游丝,唯对一位族人亲昵异常。',
options: [
{ label: '牵线认主', hint: '随机成员获得灵兽伴侣', eff: { memberBy: { by: 'genius', target: 'highestFortune', n: 1 } } },
{ label: '卖了换钱', hint: '灵石+150', eff: { res: { stones: 150 } } },
{ label: '放归山林', hint: '声望+2', eff: { rep: 2 } }
]
},
{
id: 'ev-xianyi', name: '残简偶得', category: 'major', weight: 5,
cond: { minBuilding: { id: 'cangshu', level: 1 } },
text: '有人兜售一页古玉残简,字迹晦暗,却似有大道气息流动。',
options: [
{ label: '买下参悟', hint: '灵石-150', eff: { res: { stones: -150 }, techniqueChance: 0.8 } },
{ label: '献诸官家', hint: '声望+6', eff: { rep: 6 } },
{ label: '不信邪,扔了', hint: '无', eff: {} }
]
},
{
id: 'ev-kuangxie', name: '矿脉异动', category: 'major', weight: 4,
cond: { minBuilding: { id: 'lingkuang', level: 2 } },
text: '矿工急报:井下竟听到龙吟之声,地气翻涌,恐是宝脉将成。',
options: [
{ label: '加派人手', hint: '灵矿+80', eff: { res: { lingkuang: 80 } } },
{ label: '镇压封脉', hint: '灵矿-20,声望+3', eff: { res: { lingkuang: -20 }, rep: 3 } },
{ label: '上报求封赏', hint: '灵石+100,声望+5', eff: { res: { stones: 100 }, rep: 5 } }
]
},
{
id: 'ev-yaoqi', name: '玉露灵液', category: 'major', weight: 4,
cond: { minBuilding: { id: 'yaoyuan', level: 1 } },
text: '药园一株千年石斛今夜吐露玉露,紫光浸雾,实为难得。',
options: [
{ label: '专人采露', hint: '聚气丹+2', eff: { pillGain: { 'pill-qiyuan': 2 } } },
{ label: '留作传家', hint: '声望+5', eff: { rep: 5 } },
{ label: '泡酒宴客', hint: '声望+7', eff: { rep: 7 } }
]
},
{
id: 'ev-jiazu', name: '氏族纠纷', category: 'daily', weight: 5,
cond: { minAdult: 3 },
text: '族中兄弟为一处祖屋的归属争执不下,闹到了宗祠。',
options: [
{ label: '秉公裁断', hint: '声望+3', eff: { rep: 3, memberBy: { by: 'wound', target: 'random', n: 5 } } },
{ label: '各打五十大板', hint: '声望-1', eff: { rep: -1 } },
{ label: '拖到明年再说', hint: '声望-3', eff: { rep: -3 } }
]
},
{
id: 'ev-waizushao', name: '修士来投', category: 'major', weight: 5,
cond: { minRep: 20, maxAdult: 12 },
text: '一位炼气散修慕名而来,愿入庄效力,只是要一份例钱。',
options: [
{ label: '开门收下', hint: '族人+1', eff: { memberBy: { by: 'inspire', target: 'all', n: 0 }, rep: 1, flag: { recruit: true } } },
{ label: '考其心性', hint: '族人+1(或负伤)', eff: { memberBy: { by: 'loot', target: 'highestPower', n: 1 }, flag: { recruit2: true } } },
{ label: '婉拒', hint: '无', eff: {} }
]
},
{
id: 'ev-tianlei', name: '天雷淬体', category: 'fate', weight: 2,
once: true,
text: '晴空忽落一道紫雷,劈在宗祠檐角,却汇聚成光球,悬于一位弟子头顶。',
options: [
{ label: '接引练体', hint: '随机成员修为大涨', eff: { memberBy: { by: 'genius', target: 'random', n: 3 } } },
{ label: '存入玉瓶', hint: '聚气丹+3', eff: { pillGain: { 'pill-qiyuan': 3 } } },
{ label: '请道人镇压', hint: '技能+1', eff: { memberBy: { by: 'madness', target: 'random', n: 1 } } }
]
}
]