| 424 | // --- Progression --- |
| 425 | |
| 426 | finishTarget(targetIds: number[]): { |
| 427 | message: string; |
| 428 | stageCompleted: boolean; |
| 429 | progressInfo?: StageProgressInfo; |
| 430 | } { |
| 431 | if (this.state.is_finished) { |
| 432 | return { message: 'All stages already completed.', stageCompleted: false }; |
| 433 | } |
| 434 | |
| 435 | const stage = this.currentStage; |
| 436 | if (!stage) { |
| 437 | return { message: 'No current stage found.', stageCompleted: false }; |
| 438 | } |
| 439 | |
| 440 | const validTargets = Object.keys(stage.stage_targets).map(Number); |
| 441 | const newlyCompleted: number[] = []; |
| 442 | |
| 443 | for (const id of targetIds) { |
| 444 | if (validTargets.includes(id) && !this.state.completed_targets.includes(id)) { |
| 445 | this.state = { |
| 446 | ...this.state, |
| 447 | completed_targets: [...this.state.completed_targets, id], |
| 448 | }; |
| 449 | newlyCompleted.push(id); |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | if (newlyCompleted.length === 0) { |
| 454 | return { message: 'No new targets completed.', stageCompleted: false }; |
| 455 | } |
| 456 | |
| 457 | // Check if all targets in current stage are done |
| 458 | const allDone = validTargets.every((id) => this.state.completed_targets.includes(id)); |
| 459 | if (!allDone) { |
| 460 | return { |
| 461 | message: `Completed targets: [${newlyCompleted.join(', ')}]. Remaining targets in stage.`, |
| 462 | stageCompleted: false, |
| 463 | }; |
| 464 | } |
| 465 | |
| 466 | // Stage complete — advance |
| 467 | const completedStage = { index: stage.stage_index, name: stage.stage_name }; |
| 468 | this.state = { |
| 469 | ...this.state, |
| 470 | current_stage_index: this.state.current_stage_index + 1, |
| 471 | }; |
| 472 | |
| 473 | if (this.state.current_stage_index >= this.config.stage_count) { |
| 474 | this.state = { ...this.state, is_finished: true }; |
| 475 | return { |
| 476 | message: `Stage "${stage.stage_name}" completed! All stages finished!`, |
| 477 | stageCompleted: true, |
| 478 | progressInfo: { |
| 479 | stage_progress: { |
| 480 | completed_stage: completedStage, |
| 481 | total_stages_count: this.config.stage_count, |
| 482 | all_stages_finished: true, |
| 483 | }, |