| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import { type GameDefinition, type GameControl, type PunchPolicyType } from '../core/gameDefinition'
- import { type OrienteeringCourseData } from '../../utils/orienteeringCourse'
- function sortBySequence<T extends { sequence: number | null }>(items: T[]): T[] {
- return [...items].sort((a, b) => (a.sequence || 0) - (b.sequence || 0))
- }
- function buildDisplayBody(label: string, sequence: number | null): string {
- if (typeof sequence === 'number') {
- return `检查点 ${sequence} · ${label || String(sequence)}`
- }
- return label
- }
- export function buildGameDefinitionFromCourse(
- course: OrienteeringCourseData,
- controlRadiusMeters: number,
- mode: GameDefinition['mode'] = 'classic-sequential',
- autoFinishOnLastControl = true,
- punchPolicy: PunchPolicyType = 'enter-confirm',
- punchRadiusMeters = 5,
- requiresFocusSelection = false,
- skipEnabled = false,
- skipRadiusMeters = 30,
- skipRequiresConfirm = true,
- controlScoreOverrides: Record<string, number> = {},
- defaultControlScore: number | null = null,
- ): GameDefinition {
- const controls: GameControl[] = []
- for (const start of course.layers.starts) {
- controls.push({
- id: `start-${controls.length + 1}`,
- code: start.label || 'S',
- label: start.label || 'Start',
- kind: 'start',
- point: start.point,
- sequence: null,
- score: null,
- displayContent: null,
- })
- }
- for (const control of sortBySequence(course.layers.controls)) {
- const label = control.label || String(control.sequence)
- const controlId = `control-${control.sequence}`
- const score = controlId in controlScoreOverrides
- ? controlScoreOverrides[controlId]
- : defaultControlScore
- controls.push({
- id: controlId,
- code: label,
- label,
- kind: 'control',
- point: control.point,
- sequence: control.sequence,
- score,
- displayContent: {
- title: score !== null ? `收集 ${label} (+${score}分)` : `收集 ${label}`,
- body: score !== null ? `${buildDisplayBody(label, control.sequence)} · ${score}分` : buildDisplayBody(label, control.sequence),
- },
- })
- }
- for (const finish of course.layers.finishes) {
- controls.push({
- id: `finish-${controls.length + 1}`,
- code: finish.label || 'F',
- label: finish.label || 'Finish',
- kind: 'finish',
- point: finish.point,
- sequence: null,
- score: null,
- displayContent: null,
- })
- }
- return {
- id: `course-${course.title || 'default'}`,
- mode,
- title: course.title || (mode === 'score-o' ? 'Score-O' : 'Classic Sequential'),
- controlRadiusMeters,
- punchRadiusMeters,
- punchPolicy,
- requiresFocusSelection,
- skipEnabled,
- skipRadiusMeters,
- skipRequiresConfirm,
- controls,
- autoFinishOnLastControl,
- }
- }
|