1
This commit is contained in:
@@ -186,6 +186,9 @@ pub fn compile_result_draft_from_seed(
|
||||
level_name: level_name.clone(),
|
||||
picture_description,
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -243,6 +246,9 @@ pub fn build_form_draft_from_parts(
|
||||
level_name: String::new(),
|
||||
picture_description: picture_description.clone().unwrap_or_default(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -349,6 +355,9 @@ pub fn normalize_puzzle_draft(mut draft: PuzzleResultDraft) -> PuzzleResultDraft
|
||||
&draft.summary,
|
||||
),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: draft.candidates.clone(),
|
||||
selected_candidate_id: draft.selected_candidate_id.clone(),
|
||||
@@ -436,6 +445,9 @@ pub fn append_blank_puzzle_level(draft: &PuzzleResultDraft) -> PuzzleResultDraft
|
||||
),
|
||||
picture_description,
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -767,6 +779,13 @@ pub fn resolve_puzzle_level_time_limit_ms(grid_size: u32) -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn first_profile_level(profile: &PuzzleWorkProfile) -> Option<PuzzleDraftLevel> {
|
||||
normalize_puzzle_levels(profile.levels.clone(), &profile.theme_tags)
|
||||
.unwrap_or_else(|_| profile.levels.clone())
|
||||
.into_iter()
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_runtime_remaining_ms(level: &PuzzleRuntimeLevelSnapshot, now_ms: u64) -> u64 {
|
||||
let time_limit_ms = if level.time_limit_ms == 0 {
|
||||
resolve_puzzle_level_time_limit_ms_by_index(level.level_index)
|
||||
@@ -1027,6 +1046,7 @@ pub fn start_run_with_shuffle_seed_at(
|
||||
let level_config = resolve_puzzle_level_config(level_index);
|
||||
let grid_size = level_config.grid_size;
|
||||
let board = build_initial_board_with_seed(grid_size, shuffle_seed)?;
|
||||
let current_profile_level = first_profile_level(entry_profile);
|
||||
Ok(PuzzleRunSnapshot {
|
||||
run_id: run_id.clone(),
|
||||
entry_profile_id: entry_profile.profile_id.clone(),
|
||||
@@ -1038,9 +1058,8 @@ pub fn start_run_with_shuffle_seed_at(
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id,
|
||||
level_index,
|
||||
level_id: entry_profile
|
||||
.levels
|
||||
.first()
|
||||
level_id: current_profile_level
|
||||
.as_ref()
|
||||
.map(|level| level.level_id.clone()),
|
||||
grid_size,
|
||||
profile_id: entry_profile.profile_id.clone(),
|
||||
@@ -1048,6 +1067,12 @@ pub fn start_run_with_shuffle_seed_at(
|
||||
author_display_name: entry_profile.author_display_name.clone(),
|
||||
theme_tags: entry_profile.theme_tags.clone(),
|
||||
cover_image_src: entry_profile.cover_image_src.clone(),
|
||||
ui_background_image_src: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.ui_background_image_src.clone()),
|
||||
background_music: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.background_music.clone()),
|
||||
board,
|
||||
status: PuzzleRuntimeLevelStatus::Playing,
|
||||
started_at_ms,
|
||||
@@ -1297,6 +1322,7 @@ pub fn advance_next_level_at(
|
||||
let next_board = build_initial_board_with_seed(next_grid_size, shuffle_seed)?;
|
||||
let mut played_profile_ids = run.played_profile_ids.clone();
|
||||
played_profile_ids.push(next_profile.profile_id.clone());
|
||||
let current_profile_level = first_profile_level(next_profile);
|
||||
|
||||
Ok(PuzzleRunSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
@@ -1309,9 +1335,8 @@ pub fn advance_next_level_at(
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
level_index: next_level_index,
|
||||
level_id: next_profile
|
||||
.levels
|
||||
.first()
|
||||
level_id: current_profile_level
|
||||
.as_ref()
|
||||
.map(|level| level.level_id.clone()),
|
||||
grid_size: next_grid_size,
|
||||
profile_id: next_profile.profile_id.clone(),
|
||||
@@ -1319,6 +1344,12 @@ pub fn advance_next_level_at(
|
||||
author_display_name: next_profile.author_display_name.clone(),
|
||||
theme_tags: next_profile.theme_tags.clone(),
|
||||
cover_image_src: next_profile.cover_image_src.clone(),
|
||||
ui_background_image_src: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.ui_background_image_src.clone()),
|
||||
background_music: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.background_music.clone()),
|
||||
board: next_board,
|
||||
status: PuzzleRuntimeLevelStatus::Playing,
|
||||
started_at_ms,
|
||||
@@ -1370,6 +1401,7 @@ pub fn advance_to_new_work_first_level_at(
|
||||
if !played_profile_ids.contains(&next_profile.profile_id) {
|
||||
played_profile_ids.push(next_profile.profile_id.clone());
|
||||
}
|
||||
let current_profile_level = first_profile_level(next_profile);
|
||||
|
||||
Ok(PuzzleRunSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
@@ -1382,9 +1414,8 @@ pub fn advance_to_new_work_first_level_at(
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
level_index: next_level_index,
|
||||
level_id: next_profile
|
||||
.levels
|
||||
.first()
|
||||
level_id: current_profile_level
|
||||
.as_ref()
|
||||
.map(|level| level.level_id.clone()),
|
||||
grid_size,
|
||||
profile_id: next_profile.profile_id.clone(),
|
||||
@@ -1392,6 +1423,12 @@ pub fn advance_to_new_work_first_level_at(
|
||||
author_display_name: next_profile.author_display_name.clone(),
|
||||
theme_tags: next_profile.theme_tags.clone(),
|
||||
cover_image_src: next_profile.cover_image_src.clone(),
|
||||
ui_background_image_src: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.ui_background_image_src.clone()),
|
||||
background_music: current_profile_level
|
||||
.as_ref()
|
||||
.and_then(|level| level.background_music.clone()),
|
||||
board: next_board,
|
||||
status: PuzzleRuntimeLevelStatus::Playing,
|
||||
started_at_ms,
|
||||
@@ -2802,6 +2839,9 @@ mod tests {
|
||||
level_name: format!("{profile_id} 关"),
|
||||
picture_description: "summary".to_string(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -3017,6 +3057,9 @@ mod tests {
|
||||
level_name: "第一关".to_string(),
|
||||
picture_description: "第一关画面".to_string(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -3029,6 +3072,9 @@ mod tests {
|
||||
level_name: "第二关".to_string(),
|
||||
picture_description: "第二关画面".to_string(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -3072,6 +3118,30 @@ mod tests {
|
||||
assert_eq!(next_level.time_limit_ms, 210_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn start_run_carries_first_level_background_music() {
|
||||
let mut profile = build_published_profile("entry", "owner-a", vec!["奇幻"]);
|
||||
profile.levels[0].background_music = Some(PuzzleAudioAsset {
|
||||
task_id: "suno-task-1".to_string(),
|
||||
provider: "vector-engine-suno".to_string(),
|
||||
asset_object_id: Some("assetobj_1".to_string()),
|
||||
asset_kind: Some("puzzle_background_music".to_string()),
|
||||
audio_src: "/generated-puzzle-assets/background.mp3".to_string(),
|
||||
prompt: Some(String::new()),
|
||||
title: Some("奇境初见".to_string()),
|
||||
updated_at: Some("2026-05-12T00:00:00Z".to_string()),
|
||||
});
|
||||
|
||||
let run = start_run("run-music".to_string(), &profile, 0).expect("run");
|
||||
|
||||
assert_eq!(
|
||||
run.current_level
|
||||
.and_then(|level| level.background_music)
|
||||
.map(|music| music.audio_src),
|
||||
Some("/generated-puzzle-assets/background.mp3".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap_pieces_marks_cleared_when_back_to_origin() {
|
||||
let profile = build_published_profile("entry", "owner-a", vec!["蒸汽城市", "雨夜", "猫咪"]);
|
||||
|
||||
Reference in New Issue
Block a user