1
This commit is contained in:
@@ -53,23 +53,37 @@ const PUZZLE_STEPS = [
|
||||
{
|
||||
id: 'compile',
|
||||
label: '编译首关草稿',
|
||||
detail: '根据画面描述生成首关名称和结果页草稿。',
|
||||
weight: 34,
|
||||
detail: '理解画面描述,生成首关名称与可编辑草稿。',
|
||||
weight: 20,
|
||||
},
|
||||
{
|
||||
id: 'puzzle-images',
|
||||
label: '生成首关画面',
|
||||
detail: '按画面描述和参考图生成第一张拼图图。',
|
||||
weight: 33,
|
||||
detail: '调用图片模型生成适合切块的正方形首图。',
|
||||
weight: 70,
|
||||
},
|
||||
{
|
||||
id: 'puzzle-select-image',
|
||||
label: '写入正式草稿',
|
||||
detail: '把首图设为正式图并同步到结果页。',
|
||||
weight: 33,
|
||||
detail: '确认首图并同步关卡数据,准备进入结果页。',
|
||||
weight: 10,
|
||||
},
|
||||
] as const satisfies ReadonlyArray<MiniGameStepDefinition>;
|
||||
|
||||
const PUZZLE_ESTIMATED_WAIT_MS = 60_000;
|
||||
const PUZZLE_NON_READY_MAX_PROGRESS = 98;
|
||||
const PUZZLE_PHASE_TIMELINE: Array<{
|
||||
phase: Extract<
|
||||
MiniGameDraftGenerationPhase,
|
||||
'compile' | 'puzzle-images' | 'puzzle-select-image'
|
||||
>;
|
||||
durationMs: number;
|
||||
}> = [
|
||||
{ phase: 'compile', durationMs: 12_000 },
|
||||
{ phase: 'puzzle-images', durationMs: 42_000 },
|
||||
{ phase: 'puzzle-select-image', durationMs: 6_000 },
|
||||
];
|
||||
|
||||
const BIG_FISH_STEPS = [
|
||||
{
|
||||
id: 'big-fish-draft',
|
||||
@@ -141,6 +155,7 @@ function buildMiniGameProgressSteps(
|
||||
steps: ReadonlyArray<MiniGameStepDefinition>,
|
||||
activeStepIndex: number,
|
||||
state: MiniGameDraftGenerationState,
|
||||
activeStepProgressRatio: number,
|
||||
) {
|
||||
return steps.map((step, index) => {
|
||||
const isCompleted = state.phase === 'ready' || index < activeStepIndex;
|
||||
@@ -152,7 +167,13 @@ function buildMiniGameProgressSteps(
|
||||
id: step.id,
|
||||
label: step.label,
|
||||
detail: step.detail,
|
||||
completed: isCompleted ? 1 : isAssetStep ? state.completedAssetCount : 0,
|
||||
completed: isCompleted
|
||||
? 1
|
||||
: isAssetStep
|
||||
? state.completedAssetCount
|
||||
: isActive
|
||||
? activeStepProgressRatio
|
||||
: 0,
|
||||
total: isAssetStep ? state.totalAssetCount : 1,
|
||||
status: isCompleted ? 'completed' : isActive ? 'active' : 'pending',
|
||||
} satisfies CustomWorldGenerationStep;
|
||||
@@ -201,6 +222,31 @@ function resolveSquareHolePhaseByElapsedMs(
|
||||
return 'square-hole-draft';
|
||||
}
|
||||
|
||||
function resolvePuzzleTimelineByElapsedMs(elapsedMs: number) {
|
||||
let elapsedBeforePhase = 0;
|
||||
|
||||
for (const item of PUZZLE_PHASE_TIMELINE) {
|
||||
const elapsedInPhase = elapsedMs - elapsedBeforePhase;
|
||||
|
||||
if (elapsedInPhase < item.durationMs) {
|
||||
return {
|
||||
phase: item.phase,
|
||||
activeStepProgressRatio: Math.max(
|
||||
0,
|
||||
Math.min(1, elapsedInPhase / item.durationMs),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
elapsedBeforePhase += item.durationMs;
|
||||
}
|
||||
|
||||
return {
|
||||
phase: 'puzzle-select-image' as const,
|
||||
activeStepProgressRatio: 1,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildMiniGameDraftGenerationProgress(
|
||||
state: MiniGameDraftGenerationState | null,
|
||||
nowMs = Date.now(),
|
||||
@@ -210,8 +256,19 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
}
|
||||
|
||||
const elapsedMs = Math.max(0, nowMs - state.startedAtMs);
|
||||
const puzzleTimeline =
|
||||
state.kind === 'puzzle' &&
|
||||
state.phase !== 'failed' &&
|
||||
state.phase !== 'ready'
|
||||
? resolvePuzzleTimelineByElapsedMs(elapsedMs)
|
||||
: null;
|
||||
const normalizedState =
|
||||
state.kind === 'big-fish' &&
|
||||
puzzleTimeline != null
|
||||
? {
|
||||
...state,
|
||||
phase: puzzleTimeline.phase,
|
||||
}
|
||||
: state.kind === 'big-fish' &&
|
||||
state.phase !== 'failed' &&
|
||||
state.phase !== 'ready'
|
||||
? {
|
||||
@@ -244,6 +301,8 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
)
|
||||
: normalizedState.phase === 'ready'
|
||||
? 1
|
||||
: normalizedState.kind === 'puzzle'
|
||||
? (puzzleTimeline?.activeStepProgressRatio ?? 0)
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? 0.55
|
||||
: normalizedState.kind === 'square-hole'
|
||||
@@ -255,6 +314,12 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
: normalizedState.phase === 'ready'
|
||||
? 100
|
||||
: completedWeight + activeStep.weight * assetRatio;
|
||||
const cappedOverallProgress =
|
||||
normalizedState.phase === 'ready' || normalizedState.phase === 'failed'
|
||||
? overallProgress
|
||||
: normalizedState.kind === 'puzzle'
|
||||
? Math.min(PUZZLE_NON_READY_MAX_PROGRESS, overallProgress)
|
||||
: overallProgress;
|
||||
|
||||
return {
|
||||
phaseId: normalizedState.phase,
|
||||
@@ -272,20 +337,27 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
: '首关草稿与正式图已准备完成,可进入结果页补作品信息。'
|
||||
: activeStep.detail),
|
||||
batchLabel: activeStep.label,
|
||||
overallProgress: clampProgress(overallProgress),
|
||||
completedWeight: clampProgress(overallProgress),
|
||||
overallProgress: clampProgress(cappedOverallProgress),
|
||||
completedWeight: clampProgress(cappedOverallProgress),
|
||||
totalWeight: 100,
|
||||
elapsedMs,
|
||||
estimatedRemainingMs:
|
||||
normalizedState.phase === 'ready'
|
||||
? 0
|
||||
: normalizedState.kind === 'puzzle'
|
||||
? Math.max(0, PUZZLE_ESTIMATED_WAIT_MS - elapsedMs)
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? Math.max(0, 7_000 - elapsedMs)
|
||||
: normalizedState.kind === 'square-hole'
|
||||
? Math.max(0, 12_000 - elapsedMs)
|
||||
: null,
|
||||
activeStepIndex,
|
||||
steps: buildMiniGameProgressSteps(steps, activeStepIndex, normalizedState),
|
||||
steps: buildMiniGameProgressSteps(
|
||||
steps,
|
||||
activeStepIndex,
|
||||
normalizedState,
|
||||
assetRatio,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user