完善文创展示控制与结果层基础

This commit is contained in:
2026-03-27 09:41:48 +08:00
parent 33edfba392
commit 0e025c3426
14 changed files with 1153 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ import { lonLatToWorldTile, webMercatorToLonLat, type LonLatPoint } from './proj
import { parseOrienteeringCourseKml, type OrienteeringCourseData } from './orienteeringCourse'
import { mergeGameAudioConfig, type AudioCueKey, type GameAudioConfig, type GameAudioConfigOverrides, type PartialAudioCueConfig } from '../game/audio/audioConfig'
import { mergeTelemetryConfig, type TelemetryConfig } from '../game/telemetry/telemetryConfig'
import { type GameControlDisplayContentOverride } from '../game/core/gameDefinition'
import {
mergeGameHapticsConfig,
mergeGameUiEffectsConfig,
@@ -55,6 +56,7 @@ export interface RemoteMapConfig {
skipRequiresConfirm: boolean
autoFinishOnLastControl: boolean
controlScoreOverrides: Record<string, number>
controlContentOverrides: Record<string, GameControlDisplayContentOverride>
defaultControlScore: number | null
telemetryConfig: TelemetryConfig
audioConfig: GameAudioConfig
@@ -81,6 +83,7 @@ interface ParsedGameConfig {
skipRequiresConfirm: boolean
autoFinishOnLastControl: boolean
controlScoreOverrides: Record<string, number>
controlContentOverrides: Record<string, GameControlDisplayContentOverride>
defaultControlScore: number | null
telemetryConfig: TelemetryConfig
audioConfig: GameAudioConfig
@@ -759,6 +762,7 @@ function parseGameConfigFromJson(text: string, gameConfigUrl: string): ParsedGam
? rawPlayfield.controlOverrides as Record<string, unknown>
: null
const controlScoreOverrides: Record<string, number> = {}
const controlContentOverrides: Record<string, GameControlDisplayContentOverride> = {}
if (rawControlOverrides) {
const keys = Object.keys(rawControlOverrides)
for (const key of keys) {
@@ -770,6 +774,27 @@ function parseGameConfigFromJson(text: string, gameConfigUrl: string): ParsedGam
if (Number.isFinite(scoreValue)) {
controlScoreOverrides[key] = scoreValue
}
const titleValue = typeof (item as Record<string, unknown>).title === 'string'
? ((item as Record<string, unknown>).title as string).trim()
: ''
const bodyValue = typeof (item as Record<string, unknown>).body === 'string'
? ((item as Record<string, unknown>).body as string).trim()
: ''
const autoPopupValue = (item as Record<string, unknown>).autoPopup
const onceValue = (item as Record<string, unknown>).once
const priorityNumeric = Number((item as Record<string, unknown>).priority)
const hasAutoPopup = typeof autoPopupValue === 'boolean'
const hasOnce = typeof onceValue === 'boolean'
const hasPriority = Number.isFinite(priorityNumeric)
if (titleValue || bodyValue || hasAutoPopup || hasOnce || hasPriority) {
controlContentOverrides[key] = {
...(titleValue ? { title: titleValue } : {}),
...(bodyValue ? { body: bodyValue } : {}),
...(hasAutoPopup ? { autoPopup: !!autoPopupValue } : {}),
...(hasOnce ? { once: !!onceValue } : {}),
...(hasPriority ? { priority: Math.max(0, Math.round(priorityNumeric)) } : {}),
}
}
}
}
@@ -859,6 +884,7 @@ function parseGameConfigFromJson(text: string, gameConfigUrl: string): ParsedGam
true,
),
controlScoreOverrides,
controlContentOverrides,
defaultControlScore: rawScoring && rawScoring.defaultControlScore !== undefined
? parsePositiveNumber(rawScoring.defaultControlScore, 10)
: null,
@@ -921,6 +947,7 @@ function parseGameConfigFromYaml(text: string, gameConfigUrl: string): ParsedGam
skipRequiresConfirm: parseBoolean(config.skiprequiresconfirm, true),
autoFinishOnLastControl: parseBoolean(config.autofinishonlastcontrol, true),
controlScoreOverrides: {},
controlContentOverrides: {},
defaultControlScore: null,
telemetryConfig: parseTelemetryConfig({
heartRate: {
@@ -1206,6 +1233,7 @@ export async function loadRemoteMapConfig(gameConfigUrl: string): Promise<Remote
skipRequiresConfirm: gameConfig.skipRequiresConfirm,
autoFinishOnLastControl: gameConfig.autoFinishOnLastControl,
controlScoreOverrides: gameConfig.controlScoreOverrides,
controlContentOverrides: gameConfig.controlContentOverrides,
defaultControlScore: gameConfig.defaultControlScore,
telemetryConfig: gameConfig.telemetryConfig,
audioConfig: gameConfig.audioConfig,