v2完整版:VoxCPM2语音 + 多轮对话 + 文档重写

- 用VoxCPM2生成128条v2语音(林夏回应+NPC反应+Round3对话)
- story.js全部切换到VoxCPM2音频路径
- engine.js: BGM音量减半(0.2→0.1)、MSG-14前导语支持、结局E用周南新语音
- 林夏.md完整重写:6手势交互、主角有声音、VoxCPM2本地TTS方案
- batch_tts_voxcpm.py: 新增linxia角色、修复self_3y音色、添加全部v2台词
- 新增voice/linxia/参考音色

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
xsl
2026-05-19 14:38:28 +08:00
co-authored by Claude Opus 4.6
parent 0f1b70b1a9
commit 3f53623f12
133 changed files with 1087 additions and 498 deletions
+21 -10
View File
@@ -78,7 +78,7 @@ class GameEngine {
await Snd.startAmbience(AMBIENCE_DEFAULT, { vol: 0.15 });
await sleep(1500);
Snd.startBGM(`${MUS}/lv11_bgm_m1_main_loop_v1.mp3`, { vol: 0.2 });
Snd.startBGM(`${MUS}/lv11_bgm_m1_main_loop_v1.mp3`, { vol: 0.1 });
await sleep(1500);
this._next();
@@ -208,15 +208,25 @@ class GameEngine {
this.state = 'responding';
await this._playVoiceAsync([msg.autoReply]);
// 条件反应(MSG-14:根据 MOM_LINK 播放不同反应)
// 条件反应(MSG-14先播前导语"真的没事?",再根据 MOM_LINK 播放不同反应)
if (!this._skipRequested && msg.autoReact) {
const val = this.vars[msg.autoReact.condition];
const reactUrl = val ? msg.autoReact['true'] : msg.autoReact['false'];
if (reactUrl) {
this.state = 'reacting';
this.state = 'reacting';
// 前导语(如"真的没事?")
if (msg.autoReactPreamble) {
await sleep(500);
if (!this._skipRequested) {
await this._playVoiceAsync([reactUrl]);
await this._playVoiceAsync([msg.autoReactPreamble]);
}
}
// 条件分支反应
if (!this._skipRequested) {
const val = this.vars[msg.autoReact.condition];
const reactUrl = val ? msg.autoReact['true'] : msg.autoReact['false'];
if (reactUrl) {
await sleep(400);
if (!this._skipRequested) {
await this._playVoiceAsync([reactUrl]);
}
}
}
}
@@ -253,7 +263,7 @@ class GameEngine {
this.msgState[msg.id] = 'read';
this.vars.UNREAD = Math.max(0, this.vars.UNREAD - 1);
if (msg.bgm) Snd.startBGM(msg.bgm, { vol: 0.2 });
if (msg.bgm) Snd.startBGM(msg.bgm, { vol: 0.1 });
// 系统通知(时光胶囊)
if (msg.type === 'system_notification') {
@@ -687,9 +697,10 @@ class GameEngine {
async _endingE() {
Haptic.message();
SFX_UI.notify();
await sleep(1500);
// 周南秒回:"那我下次出差来北京,请你吃饭好不好。"
await this._playVoiceAsync([`${T}/v2_ending_e_zhounan_wav_v1.mp3`]);
await sleep(2000);
Snd.playVoice([`${TDIR}/lv11_sys_goodnight_wav_v1.mp3`]);
await sleep(3000);
SFX_UI.ending();
await sleep(1000);
this._showCaption('好。');
+193 -178
View File
@@ -1,4 +1,4 @@
// story.js — 消息数据 v2(多轮对话 + 林夏语音 + NPC反应
// story.js — 消息数据 v2VoxCPM2 语音 + 多轮对话)
//
// 选择方向的情感含义(全局一致):
// 单击(tap) → 简单回应
@@ -16,61 +16,64 @@
// profile: 画像分数变更
// followUp: 可选的下一轮对话 { choices: { ... } }
const A = '../audio/mp3';
const TDIR = `${A}/tts`;
const LINXIA = `${A}/linxia`;
const REACT = `${A}/react`;
const MUS = `${A}/music`;
const SFX = `${A}/sfx`;
const AMB = `${A}/ambience`;
const A = '../audio/mp3';
const T = `${A}/tts`; // VoxCPM2 生成的所有语音
const MUS = `${A}/music`;
const SFX = `${A}/sfx`;
const AMB = `${A}/ambience`;
// ── 快捷函数 ──
const npc = f => `${T}/${f}`; // NPC Round 1 台词
const lx = f => `${T}/${f}`; // 林夏回应
const rx = f => `${T}/${f}`; // NPC 反应
const MESSAGES = [
// ══════════════════════════════════════════
// 01 · 妈妈 · 电话(教学:接/拒电话)
// 01 · 妈妈 · 电话
// ══════════════════════════════════════════
{
id: 1, type: 'call',
sender: 'mom', senderName: '妈妈',
ringtone: `${MUS}/lv11_ring_mom_v1.mp3`,
audio: [`${TDIR}/lv11_2103_mom_call_01_wav_v1.mp3`],
autoReply: `${LINXIA}/msg01_auto.mp3`,
audio: [npc('lv11_2103_mom_call_01_wav_v1.mp3')],
autoReply: lx('v2_msg01_linxia_auto_wav_v1.mp3'),
stateOnAnswer: { MOM_LINK: true },
profileOnMiss: { avoidance: 2 },
profileOnAnswer: { engagement: 1 },
},
// ══════════════════════════════════════════
// 02 · 小美 · 微信语音 ×3(教学:选择系统
// 02 · 小美 · 语音 ×3(教学
// ══════════════════════════════════════════
{
id: 2, type: 'wechat_voice',
sender: 'xiaomei', senderName: '小美',
audio: [
`${TDIR}/lv11_2115_xiaomei_voice_01_wav_v1.mp3`,
`${TDIR}/lv11_2115_xiaomei_voice_02_wav_v1.mp3`,
`${TDIR}/lv11_2115_xiaomei_voice_03_wav_v1.mp3`,
npc('lv11_2115_xiaomei_voice_01_wav_v1.mp3'),
npc('lv11_2115_xiaomei_voice_02_wav_v1.mp3'),
npc('lv11_2115_xiaomei_voice_03_wav_v1.mp3'),
],
choices: {
right: {
linxia: `${LINXIA}/msg02_warm.mp3`,
npcReact: [`${REACT}/msg02_react_warm.mp3`],
linxia: lx('v2_msg02_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg02_react_warm_wav_v1.mp3')],
profile: { engagement: 2 },
},
left: {
linxia: `${LINXIA}/msg02_cold.mp3`,
npcReact: [`${REACT}/msg02_react_cold.mp3`],
linxia: lx('v2_msg02_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg02_react_cold_wav_v1.mp3')],
profile: { avoidance: 1 },
},
up: {
linxia: `${LINXIA}/msg02_curious.mp3`,
npcReact: [`${REACT}/msg02_react_curious.mp3`],
linxia: lx('v2_msg02_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg02_react_curious_wav_v1.mp3')],
profile: { engagement: 1 },
followUp: {
choices: {
right: {
linxia: `${LINXIA}/msg02_r3_curious.mp3`,
npcReact: [`${REACT}/msg02_r3_curious.mp3`],
linxia: lx('v2_msg02_r3_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg02_r3_react_wav_v1.mp3')],
profile: { nostalgia: 1 },
},
},
@@ -78,90 +81,92 @@ const MESSAGES = [
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg02_react_silent.mp3`],
npcReact: [rx('v2_msg02_react_silent_wav_v1.mp3')],
profile: { avoidance: 2 },
},
tap: {
linxia: `${LINXIA}/generic_hmm.mp3`,
npcReact: [`${REACT}/msg02_react_tap.mp3`],
linxia: lx('v2_msg02_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg02_react_tap_wav_v1.mp3')],
},
},
},
// ══════════════════════════════════════════
// 03 · 外卖小哥 · 电话(日常感)
// 03 · 外卖小哥 · 电话
// ══════════════════════════════════════════
{
id: 3, type: 'call',
sender: 'delivery', senderName: '外卖小哥',
ringtone: `${MUS}/lv11_ring_delivery_v1.mp3`,
audio: [`${TDIR}/lv11_2120_delivery_call_01_wav_v1.mp3`],
autoReply: `${LINXIA}/msg03_auto.mp3`,
audio: [npc('lv11_2120_delivery_call_01_wav_v1.mp3')],
autoReply: lx('v2_msg03_linxia_auto_wav_v1.mp3'),
profileOnMiss: { avoidance: 1 },
profileOnAnswer: { engagement: 1 },
},
// ══════════════════════════════════════════
// 04 · 阿哲 · 微信语音(前男友要东西)
// 04 · 阿哲 · 语音(前男友要东西)
// ══════════════════════════════════════════
{
id: 4, type: 'wechat_voice',
sender: 'azhe', senderName: '阿哲',
audio: [`${TDIR}/lv11_2130_azhe_voice_01_wav_v1.mp3`],
audio: [npc('lv11_2130_azhe_voice_01_wav_v1.mp3')],
choices: {
right: {
linxia: `${LINXIA}/msg04_warm.mp3`,
npcReact: [`${REACT}/msg04_react_warm.mp3`],
linxia: lx('v2_msg04_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg04_react_warm_wav_v1.mp3')],
profile: { engagement: 2 },
followUp: {
// 阿哲问"你呢?"后
choices: {
right: {
linxia: `${LINXIA}/msg04_r3w_warm.mp3`,
npcReact: [`${REACT}/msg04_r3w_sorry.mp3`],
linxia: lx('v2_msg04_r3w_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg04_r3w_react_warm_wav_v1.mp3')],
},
left: {
linxia: `${LINXIA}/msg04_r3w_cold.mp3`,
npcReact: [`${REACT}/msg04_r3w_good.mp3`],
linxia: lx('v2_msg04_r3w_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg04_r3w_react_cold_wav_v1.mp3')],
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg04_r3w_night.mp3`],
npcReact: [rx('v2_msg04_r3w_react_silent_wav_v1.mp3')],
},
},
},
},
left: {
linxia: `${LINXIA}/msg04_cold.mp3`,
npcReact: [`${REACT}/msg04_react_cold.mp3`],
linxia: lx('v2_msg04_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg04_react_cold_wav_v1.mp3')],
state: { HE_BACK: false },
profile: { avoidance: 1 },
},
up: {
linxia: `${LINXIA}/msg04_curious.mp3`,
npcReact: [`${REACT}/msg04_react_curious.mp3`],
linxia: lx('v2_msg04_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg04_react_curious_wav_v1.mp3')],
profile: { engagement: 2 },
followUp: {
// 阿哲说"不太方便"后
choices: {
up: {
linxia: `${LINXIA}/msg04_r3c_curious.mp3`,
npcReact: [`${REACT}/msg04_r3c_nevermind.mp3`],
linxia: lx('v2_msg04_r3c_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg04_r3c_react_curious_wav_v1.mp3')],
state: { HE_BACK: false },
},
right: {
linxia: `${LINXIA}/msg04_r3c_warm.mp3`,
linxia: lx('v2_msg04_r3c_linxia_warm_wav_v1.mp3'),
},
},
},
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg04_react_silent.mp3`],
npcReact: [rx('v2_msg04_react_silent_wav_v1.mp3')],
state: { HE_BACK: null },
profile: { avoidance: 2 },
},
tap: {
linxia: `${LINXIA}/generic_ok.mp3`,
npcReact: [`${REACT}/msg04_react_tap.mp3`],
linxia: lx('v2_msg04_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg04_react_tap_wav_v1.mp3')],
state: { HE_BACK: false },
profile: { engagement: 1 },
},
@@ -169,24 +174,24 @@ const MESSAGES = [
},
// ══════════════════════════════════════════
// 05 · HR王姐 · 微信语音
// 05 · HR王姐 · 语音
// ══════════════════════════════════════════
{
id: 5, type: 'wechat_voice',
sender: 'hr', senderName: 'HR王姐',
audio: [`${TDIR}/lv11_2145_hr_voice_01_wav_v1.mp3`],
audio: [npc('lv11_2145_hr_voice_01_wav_v1.mp3')],
choices: {
right: {
linxia: `${LINXIA}/msg05_warm.mp3`,
npcReact: [`${REACT}/msg05_react_warm.mp3`],
linxia: lx('v2_msg05_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg05_react_warm_wav_v1.mp3')],
profile: { engagement: 1 },
},
left: {
linxia: `${LINXIA}/msg05_cold.mp3`,
linxia: lx('v2_msg05_linxia_cold_wav_v1.mp3'),
},
up: {
linxia: `${LINXIA}/msg05_curious.mp3`,
npcReact: [`${REACT}/msg05_react_curious.mp3`],
linxia: lx('v2_msg05_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg05_react_curious_wav_v1.mp3')],
profile: { engagement: 2 },
},
down: {
@@ -194,84 +199,85 @@ const MESSAGES = [
profile: { avoidance: 1 },
},
tap: {
linxia: `${LINXIA}/generic_ok.mp3`,
linxia: lx('v2_msg05_linxia_tap_wav_v1.mp3'),
},
},
},
// ══════════════════════════════════════════
// 06 · 安安 · 微信语音(酒吧邀约)
// 06 · 安安 · 语音(酒吧邀约)
// ══════════════════════════════════════════
{
id: 6, type: 'wechat_voice',
sender: 'anan', senderName: '安安',
audio: [`${TDIR}/lv11_2200_anan_voice_01_wav_v1.mp3`],
audio: [npc('lv11_2200_anan_voice_01_wav_v1.mp3')],
choices: {
right: {
linxia: `${LINXIA}/msg06_warm.mp3`,
npcReact: [`${REACT}/msg06_react_warm.mp3`],
linxia: lx('v2_msg06_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg06_react_warm_wav_v1.mp3')],
profile: { engagement: 2 },
},
left: {
linxia: `${LINXIA}/msg06_cold.mp3`,
npcReact: [`${REACT}/msg06_react_cold.mp3`],
linxia: lx('v2_msg06_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg06_react_cold_wav_v1.mp3')],
},
up: {
linxia: `${LINXIA}/msg06_curious.mp3`,
npcReact: [`${REACT}/msg06_react_curious.mp3`],
linxia: lx('v2_msg06_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg06_react_curious_wav_v1.mp3')],
profile: { engagement: 1 },
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg06_react_silent.mp3`],
npcReact: [rx('v2_msg06_react_silent_wav_v1.mp3')],
profile: { avoidance: 1 },
},
tap: {
linxia: `${LINXIA}/generic_hmm.mp3`,
npcReact: [`${REACT}/msg06_react_tap.mp3`],
linxia: lx('v2_msg06_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg06_react_tap_wav_v1.mp3')],
},
},
},
// ══════════════════════════════════════════
// 07 · 大学寝室群 · 5条语音
// 07 · 寝室群 · 5条语音
// ══════════════════════════════════════════
{
id: 7, type: 'wechat_voice',
sender: 'dorm', senderName: '寝室群',
audio: [
`${TDIR}/lv11_2215_dorm_a_voice_01_wav_v1.mp3`,
`${TDIR}/lv11_2215_dorm_a_voice_02_wav_v1.mp3`,
`${TDIR}/lv11_2215_dorm_b_voice_01_wav_v1.mp3`,
`${TDIR}/lv11_2215_dorm_b_voice_02_wav_v1.mp3`,
`${TDIR}/lv11_2215_dorm_c_voice_01_wav_v1.mp3`,
npc('lv11_2215_dorm_a_voice_01_wav_v1.mp3'),
npc('lv11_2215_dorm_b_voice_01_wav_v1.mp3'),
npc('lv11_2215_dorm_c_voice_01_wav_v1.mp3'),
npc('lv11_2215_dorm_a_voice_02_wav_v1.mp3'),
npc('lv11_2215_dorm_b_voice_02_wav_v1.mp3'),
],
choices: {
right: {
linxia: `${LINXIA}/msg07_warm.mp3`,
npcReact: [`${REACT}/msg07_react_warm.mp3`],
linxia: lx('v2_msg07_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg07_react_warm_wav_v1.mp3')],
state: { GROUP_REPLY: true },
profile: { engagement: 2 },
followUp: {
// 室友A问"你最近怎么样"后
choices: {
right: {
linxia: `${LINXIA}/msg07_r3_warm.mp3`,
linxia: lx('v2_msg07_r3_linxia_warm_wav_v1.mp3'),
profile: { engagement: 1 },
},
left: {
linxia: `${LINXIA}/msg07_r3_cold.mp3`,
npcReact: [`${REACT}/msg07_r3_cold.mp3`],
linxia: lx('v2_msg07_r3_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg07_r3_react_cold_wav_v1.mp3')],
},
},
},
},
left: {
linxia: `${LINXIA}/msg07_cold.mp3`,
linxia: lx('v2_msg07_linxia_cold_wav_v1.mp3'),
profile: { avoidance: 1 },
},
up: {
linxia: `${LINXIA}/msg07_curious.mp3`,
npcReact: [`${REACT}/msg07_react_curious.mp3`],
linxia: lx('v2_msg07_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg07_react_curious_wav_v1.mp3')],
state: { GROUP_REPLY: true },
profile: { engagement: 2 },
},
@@ -280,8 +286,8 @@ const MESSAGES = [
profile: { avoidance: 2 },
},
tap: {
linxia: `${LINXIA}/generic_hmm.mp3`,
npcReact: [`${REACT}/msg07_react_tap.mp3`],
linxia: lx('v2_linxia_generic_hmm_wav_v1.mp3'),
npcReact: [rx('v2_msg07_react_tap_wav_v1.mp3')],
state: { GROUP_REPLY: true },
},
},
@@ -302,41 +308,46 @@ const MESSAGES = [
},
// ══════════════════════════════════════════
// 09 · 小美(醉)· 4段语音(秘密揭露)
// 09 · 小美(醉)· 4段语音
// ══════════════════════════════════════════
{
id: 9, type: 'wechat_voice',
sender: 'xiaomei', senderName: '小美',
audio: [
`${TDIR}/lv11_2245_xiaomei_voice_01_seg1_wav_v1.mp3`,
`${TDIR}/lv11_2245_xiaomei_voice_01_seg2_wav_v1.mp3`,
`${TDIR}/lv11_2245_xiaomei_voice_01_seg3_wav_v1.mp3`,
`${TDIR}/lv11_2245_xiaomei_voice_01_seg4_wav_v1.mp3`,
npc('lv11_2245_xiaomei_voice_01_seg1_wav_v1.mp3'),
npc('lv11_2245_xiaomei_voice_01_seg2_wav_v1.mp3'),
npc('lv11_2245_xiaomei_voice_01_seg3_wav_v1.mp3'),
npc('lv11_2245_xiaomei_voice_01_seg4_wav_v1.mp3'),
],
bgm: `${MUS}/lv11_bgm_m2_suspense_v1.mp3`,
choices: {
right: {
linxia: `${LINXIA}/msg09_warm.mp3`,
npcReact: [`${REACT}/msg09_react_warm.mp3`],
linxia: lx('v2_msg09_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg09_react_warm_wav_v1.mp3')],
profile: { engagement: 2 },
},
left: {
linxia: `${LINXIA}/msg09_cold.mp3`,
linxia: lx('v2_msg09_linxia_cold_wav_v1.mp3'),
profile: { avoidance: 1 },
},
up: {
linxia: `${LINXIA}/msg09_curious.mp3`,
npcReact: [`${REACT}/msg09_react_curious.mp3`],
linxia: lx('v2_msg09_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg09_react_curious_wav_v1.mp3')],
profile: { engagement: 2 },
followUp: {
// 小美说"怕你恨我"后
choices: {
right: {
linxia: `${LINXIA}/msg09_r3_warm.mp3`,
npcReact: [`${REACT}/msg09_r3_warm.mp3`],
linxia: lx('v2_msg09_r3_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg09_r3_react_warm_wav_v1.mp3')],
},
left: {
linxia: `${LINXIA}/msg09_r3_cold.mp3`,
npcReact: [`${REACT}/msg09_r3_cold.mp3`],
linxia: lx('v2_msg09_r3_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg09_r3_react_cold_wav_v1.mp3')],
},
down: {
isSilence: true,
npcReact: [rx('v2_msg09_r3_react_silent_q_wav_v1.mp3')],
},
},
},
@@ -346,8 +357,8 @@ const MESSAGES = [
profile: { avoidance: 2, nostalgia: 1 },
},
tap: {
linxia: `${LINXIA}/generic_hmm.mp3`,
npcReact: [`${REACT}/msg09_react_tap.mp3`],
linxia: lx('v2_msg09_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg09_react_tap_wav_v1.mp3')],
profile: { nostalgia: 1 },
},
},
@@ -362,59 +373,61 @@ const MESSAGES = [
text: '睡了吗?',
choices: {
right: {
linxia: `${LINXIA}/msg10_warm.mp3`,
npcReact: [`${REACT}/msg10_react_warm.mp3`],
linxia: lx('v2_msg10_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg10_react_warm_wav_v1.mp3')],
state: { MOM_LINK: true },
profile: { engagement: 2 },
followUp: {
// 妈妈问"今天怎么样"后
choices: {
right: {
linxia: `${LINXIA}/msg10_rw_warm.mp3`,
npcReact: [`${REACT}/msg10_rw_warm.mp3`],
linxia: lx('v2_msg10_rw_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg10_rw_react_warm_wav_v1.mp3')],
},
up: {
linxia: `${LINXIA}/msg10_rw_curious.mp3`,
npcReact: [`${REACT}/msg10_rw_curious.mp3`],
linxia: lx('v2_msg10_rw_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg10_rw_react_curious_wav_v1.mp3')],
},
},
},
},
left: {
linxia: `${LINXIA}/msg10_cold.mp3`,
npcReact: [`${REACT}/msg10_react_cold.mp3`],
linxia: lx('v2_msg10_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg10_react_cold_wav_v1.mp3')],
state: { MOM_LINK: true },
profile: { avoidance: 1 },
},
up: {
linxia: `${LINXIA}/msg10_curious.mp3`,
npcReact: [`${REACT}/msg10_react_curious.mp3`],
linxia: lx('v2_msg10_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg10_call_mom_wav_v1.mp3')],
state: { MOM_LINK: true },
profile: { engagement: 3 },
followUp: {
// 妈妈打来电话说"怎么了夏夏?"后
choices: {
right: {
linxia: `${LINXIA}/msg10_call_warm.mp3`,
npcReact: [`${REACT}/msg10_call_warm.mp3`],
linxia: lx('v2_msg10_call_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg10_call_react_warm_wav_v1.mp3')],
},
up: {
linxia: `${LINXIA}/msg10_call_curious.mp3`,
npcReact: [`${REACT}/msg10_call_curious.mp3`],
linxia: lx('v2_msg10_call_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg10_call_react_curious_wav_v1.mp3')],
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg10_call_silent.mp3`],
npcReact: [rx('v2_msg10_call_react_silent_wav_v1.mp3')],
},
},
},
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg10_react_silent.mp3`],
npcReact: [rx('v2_msg10_react_silent_wav_v1.mp3')],
profile: { avoidance: 2 },
},
tap: {
linxia: `${LINXIA}/generic_hmm.mp3`,
npcReact: [`${REACT}/msg10_react_tap.mp3`],
linxia: lx('v2_msg10_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg10_react_tap_wav_v1.mp3')],
state: { MOM_LINK: true },
},
},
@@ -427,33 +440,33 @@ const MESSAGES = [
id: 11, type: 'call',
sender: 'azhe', senderName: '阿哲',
ringtone: `${MUS}/lv11_ring_azhe_v1.mp3`,
audio: [`${TDIR}/lv11_2315_azhe_call_01_wav_v1.mp3`],
audio: [npc('lv11_2315_azhe_call_01_wav_v1.mp3')],
profileOnMiss: { avoidance: 2 },
profileOnAnswer: { engagement: 1 },
choices: {
right: {
linxia: `${LINXIA}/msg11_warm.mp3`,
npcReact: [`${REACT}/msg11_react_warm.mp3`],
linxia: lx('v2_msg11_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_warm_wav_v1.mp3')],
state: { HE_BACK: true },
},
left: {
linxia: `${LINXIA}/msg11_cold.mp3`,
npcReact: [`${REACT}/msg11_react_cold.mp3`],
linxia: lx('v2_msg11_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_cold_wav_v1.mp3')],
state: { HE_BACK: false },
},
up: {
linxia: `${LINXIA}/msg11_curious.mp3`,
npcReact: [`${REACT}/msg11_react_curious.mp3`],
linxia: lx('v2_msg11_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_curious_wav_v1.mp3')],
followUp: {
choices: {
right: {
linxia: `${LINXIA}/msg11_warm.mp3`,
npcReact: [`${REACT}/msg11_react_warm.mp3`],
linxia: lx('v2_msg11_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_warm_wav_v1.mp3')],
state: { HE_BACK: true },
},
left: {
linxia: `${LINXIA}/msg11_cold.mp3`,
npcReact: [`${REACT}/msg11_react_cold.mp3`],
linxia: lx('v2_msg11_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_cold_wav_v1.mp3')],
state: { HE_BACK: false },
},
},
@@ -464,47 +477,47 @@ const MESSAGES = [
state: { HE_BACK: false },
},
tap: {
linxia: `${LINXIA}/msg11_tap.mp3`,
npcReact: [`${REACT}/msg11_react_tap.mp3`],
linxia: lx('v2_msg11_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg11_react_tap_wav_v1.mp3')],
state: { HE_BACK: false },
},
},
},
// ══════════════════════════════════════════
// 12 · 周南 · 微信语音(老同学)
// 12 · 周南 · 语音(老同学)
// ══════════════════════════════════════════
{
id: 12, type: 'wechat_voice',
sender: 'zhounan', senderName: '周南',
audio: [`${TDIR}/lv11_2330_zhounan_voice_01_wav_v1.mp3`],
audio: [npc('lv11_2330_zhounan_voice_01_wav_v1.mp3')],
choices: {
right: {
linxia: `${LINXIA}/msg12_warm.mp3`,
npcReact: [`${REACT}/msg12_react_warm.mp3`],
linxia: lx('v2_msg12_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg12_react_warm_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH: 1 },
profile: { engagement: 2, nostalgia: 1 },
},
left: {
linxia: `${LINXIA}/msg12_cold.mp3`,
npcReact: [`${REACT}/msg12_react_cold.mp3`],
linxia: lx('v2_msg12_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg12_react_cold_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH: 1 },
profile: { nostalgia: 1 },
},
up: {
linxia: `${LINXIA}/msg12_curious.mp3`,
npcReact: [`${REACT}/msg12_react_curious.mp3`],
linxia: lx('v2_msg12_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg12_react_curious_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH: 1 },
profile: { nostalgia: 2 },
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg12_react_silent.mp3`],
npcReact: [rx('v2_msg12_react_silent_wav_v1.mp3')],
profile: { nostalgia: 1 },
},
tap: {
linxia: `${LINXIA}/msg12_tap.mp3`,
npcReact: [`${REACT}/msg12_react_tap.mp3`],
linxia: lx('v2_msg12_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg12_react_tap_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH: 1 },
},
},
@@ -517,75 +530,77 @@ const MESSAGES = [
id: 13, type: 'wechat_voice',
sender: 'zhounan', senderName: '周南',
audio: [
`${TDIR}/lv11_2345_zhounan_voice_01_wav_v1.mp3`,
`${TDIR}/lv11_2345_zhounan_voice_02_wav_v1.mp3`,
`${TDIR}/lv11_2345_zhounan_voice_03_wav_v1.mp3`,
`${TDIR}/lv11_2345_zhounan_voice_04_wav_v1.mp3`,
npc('lv11_2345_zhounan_voice_01_wav_v1.mp3'),
npc('lv11_2345_zhounan_voice_02_wav_v1.mp3'),
npc('lv11_2345_zhounan_voice_03_wav_v1.mp3'),
npc('lv11_2345_zhounan_voice_04_wav_v1.mp3'),
],
bgm: `${MUS}/lv11_bgm_m3_zhounan_v1.mp3`,
choices: {
right: {
linxia: `${LINXIA}/msg13_warm.mp3`,
npcReact: [`${REACT}/msg13_react_warm.mp3`],
linxia: lx('v2_msg13_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg13_react_warm_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH_ADD: 1 },
profile: { engagement: 2 },
followUp: {
// 周南问"你在北京过得好吗"后
choices: {
right: {
linxia: `${LINXIA}/msg13_r3_warm.mp3`,
npcReact: [`${REACT}/msg13_r3_warm.mp3`],
linxia: lx('v2_msg13_r3_linxia_warm_wav_v1.mp3'),
npcReact: [rx('v2_msg13_r3_react_warm_wav_v1.mp3')],
state: { ZHOUNAN_SHARE: true },
},
left: {
linxia: `${LINXIA}/msg13_r3_cold.mp3`,
npcReact: [`${REACT}/msg13_r3_cold.mp3`],
linxia: lx('v2_msg13_r3_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg13_r3_react_cold_wav_v1.mp3')],
},
up: {
linxia: `${LINXIA}/msg13_r3_curious.mp3`,
npcReact: [`${REACT}/msg13_r3_curious.mp3`],
linxia: lx('v2_msg13_r3_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg13_r3_react_curious_wav_v1.mp3')],
},
},
},
},
left: {
linxia: `${LINXIA}/msg13_cold.mp3`,
npcReact: [`${REACT}/msg13_react_cold.mp3`],
linxia: lx('v2_msg13_linxia_cold_wav_v1.mp3'),
npcReact: [rx('v2_msg13_react_cold_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH_ADD: 1 },
profile: { nostalgia: 1 },
},
up: {
linxia: `${LINXIA}/msg13_curious.mp3`,
npcReact: [`${REACT}/msg13_react_curious.mp3`],
linxia: lx('v2_msg13_linxia_curious_wav_v1.mp3'),
npcReact: [rx('v2_msg13_react_curious_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH_ADD: 1, ZHOUNAN_SHARE: true },
profile: { nostalgia: 2, engagement: 1 },
},
down: {
isSilence: true,
npcReact: [`${REACT}/msg13_react_silent.mp3`],
npcReact: [rx('v2_msg13_react_silent_wav_v1.mp3')],
profile: { avoidance: 1 },
},
tap: {
linxia: `${LINXIA}/msg13_tap.mp3`,
npcReact: [`${REACT}/msg13_react_tap.mp3`],
linxia: lx('v2_msg13_linxia_tap_wav_v1.mp3'),
npcReact: [rx('v2_msg13_react_tap_wav_v1.mp3')],
state: { ZHOUNAN_DEPTH_ADD: 1 },
},
},
},
// ══════════════════════════════════════════
// 14 · 妈妈 · 第二次电话(自动回应 + 条件反应)
// 14 · 妈妈 · 第二次电话
// ══════════════════════════════════════════
{
id: 14, type: 'call',
sender: 'mom', senderName: '妈妈',
ringtone: `${MUS}/lv11_ring_mom_v1.mp3`,
audio: [`${TDIR}/lv11_0015_mom_call_01_wav_v1.mp3`],
autoReply: `${LINXIA}/msg14_auto.mp3`,
audio: [npc('lv11_0015_mom_call_01_wav_v1.mp3')],
autoReply: lx('v2_msg14_linxia_auto_wav_v1.mp3'),
autoReact: {
condition: 'MOM_LINK',
true: `${REACT}/msg14_react_linked.mp3`,
false: `${REACT}/msg14_react_unlinked.mp3`,
true: rx('v2_msg14_react_linked_wav_v1.mp3'),
false: rx('v2_msg14_react_unlinked_wav_v1.mp3'),
},
autoReactPreamble: rx('v2_msg14_mom_ask_wav_v1.mp3'),
stateOnAnswer: { MOM_LINK: true },
profileOnMiss: { avoidance: 2 },
profileOnAnswer: { engagement: 2 },
@@ -597,11 +612,11 @@ const MESSAGES = [
{
id: 15, type: 'system_notification',
sender: 'self', senderName: '时光胶囊',
systemAudio: `${TDIR}/lv11_sys_memo_01_wav_v1.mp3`,
systemAudio: npc('lv11_sys_memo_01_wav_v1.mp3'),
audioByProfile: {
avoidance: `${TDIR}/lv11_0030_self3y_voice_02_wav_v1.mp3`,
engagement: `${TDIR}/lv11_0030_self3y_voice_01_wav_v1.mp3`,
nostalgia: `${TDIR}/lv11_0030_self3y_voice_03_wav_v1.mp3`,
avoidance: npc('lv11_0030_self3y_voice_02_wav_v1.mp3'),
engagement: npc('lv11_0030_self3y_voice_01_wav_v1.mp3'),
nostalgia: npc('lv11_0030_self3y_voice_03_wav_v1.mp3'),
},
stateOnPlay: { SELF_RECORD: true },
profileOnPlay: { nostalgia: 2 },
@@ -609,20 +624,20 @@ const MESSAGES = [
},
// ══════════════════════════════════════════
// 16 · 妈妈 · 长语音(结局前奏)
// 16 · 妈妈 · 长语音 ×8(结局前奏)
// ══════════════════════════════════════════
{
id: 16, type: 'wechat_voice',
sender: 'mom', senderName: '妈妈',
audio: [
`${TDIR}/lv11_0200_mom_voice_01_seg1_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg2_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg3_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg4_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg5_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg6_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg7_wav_v1.mp3`,
`${TDIR}/lv11_0200_mom_voice_01_seg8_wav_v1.mp3`,
npc('lv11_0200_mom_voice_01_seg1_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg2_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg3_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg4_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg5_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg6_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg7_wav_v1.mp3'),
npc('lv11_0200_mom_voice_01_seg8_wav_v1.mp3'),
],
bgm: `${MUS}/lv11_bgm_m4_ending_v1.mp3`,
isEnding: true,