Files
cmr-mini/miniprogram/game/core/runtimeProfileCompiler.ts

151 lines
5.0 KiB
TypeScript

import { type RemoteMapConfig } from '../../utils/remoteMapConfig'
import { type GameAudioConfig } from '../audio/audioConfig'
import { type GameHapticsConfig, type GameUiEffectsConfig } from '../feedback/feedbackConfig'
import { getGameModeDefaults } from './gameModeDefaults'
import {
resolveSystemSettingsState,
type ResolvedSystemSettingsState,
} from './systemSettingsState'
import { type CourseStyleConfig } from '../presentation/courseStyleConfig'
import { type GpsMarkerStyleConfig } from '../presentation/gpsMarkerStyleConfig'
import { type TrackVisualizationConfig } from '../presentation/trackStyleConfig'
import { mergeTelemetrySources, type PlayerTelemetryProfile } from '../telemetry/playerTelemetryProfile'
import { type TelemetryConfig } from '../telemetry/telemetryConfig'
export interface RuntimeMapProfile {
title: string
tileSource: string
projectionModeText: string
magneticDeclinationText: string
cpRadiusMeters: number
projection: string
magneticDeclinationDeg: number
minZoom: number
maxZoom: number
initialZoom: number
initialCenterTileX: number
initialCenterTileY: number
tileBoundsByZoom: RemoteMapConfig['tileBoundsByZoom']
courseStatusText: string
}
export interface RuntimeGameProfile {
mode: RemoteMapConfig['gameMode']
sessionCloseAfterMs: number
sessionCloseWarningMs: number
minCompletedControlsBeforeFinish: number
punchPolicy: RemoteMapConfig['punchPolicy']
punchRadiusMeters: number
requiresFocusSelection: boolean
skipEnabled: boolean
skipRadiusMeters: number
skipRequiresConfirm: boolean
autoFinishOnLastControl: boolean
defaultControlScore: number | null
}
export interface RuntimePresentationProfile {
course: CourseStyleConfig
track: TrackVisualizationConfig
gpsMarker: GpsMarkerStyleConfig
}
export interface RuntimeFeedbackProfile {
audio: GameAudioConfig
haptics: GameHapticsConfig
uiEffects: GameUiEffectsConfig
}
export interface RuntimeTelemetryProfile {
config: TelemetryConfig
playerProfile: PlayerTelemetryProfile | null
}
export interface RuntimeSettingsProfile extends ResolvedSystemSettingsState {
lockLifetimeActive: boolean
}
export interface CompiledRuntimeProfile {
map: RuntimeMapProfile
game: RuntimeGameProfile
settings: RuntimeSettingsProfile
telemetry: RuntimeTelemetryProfile
presentation: RuntimePresentationProfile
feedback: RuntimeFeedbackProfile
}
export interface CompileRuntimeProfileOptions {
playerTelemetryProfile?: PlayerTelemetryProfile | null
settingsLockLifetimeActive?: boolean
storedSettingsKey?: string
}
export function compileRuntimeProfile(
config: RemoteMapConfig,
options?: CompileRuntimeProfileOptions,
): CompiledRuntimeProfile {
const modeDefaults = getGameModeDefaults(config.gameMode)
const lockLifetimeActive = !!(options && options.settingsLockLifetimeActive === true)
const playerTelemetryProfile = options && options.playerTelemetryProfile
? Object.assign({}, options.playerTelemetryProfile)
: null
const settings = resolveSystemSettingsState(
config.systemSettingsConfig,
options && options.storedSettingsKey ? options.storedSettingsKey : undefined,
lockLifetimeActive,
)
return {
map: {
title: config.configTitle,
tileSource: config.tileSource,
projectionModeText: config.projectionModeText,
magneticDeclinationText: config.magneticDeclinationText,
cpRadiusMeters: config.cpRadiusMeters,
projection: config.projection,
magneticDeclinationDeg: config.magneticDeclinationDeg,
minZoom: config.minZoom,
maxZoom: config.maxZoom,
initialZoom: config.defaultZoom,
initialCenterTileX: config.initialCenterTileX,
initialCenterTileY: config.initialCenterTileY,
tileBoundsByZoom: config.tileBoundsByZoom,
courseStatusText: config.courseStatusText,
},
game: {
mode: config.gameMode,
sessionCloseAfterMs: config.sessionCloseAfterMs || modeDefaults.sessionCloseAfterMs,
sessionCloseWarningMs: config.sessionCloseWarningMs || modeDefaults.sessionCloseWarningMs,
minCompletedControlsBeforeFinish: config.minCompletedControlsBeforeFinish,
punchPolicy: config.punchPolicy,
punchRadiusMeters: config.punchRadiusMeters,
requiresFocusSelection: config.requiresFocusSelection,
skipEnabled: config.skipEnabled,
skipRadiusMeters: config.skipRadiusMeters,
skipRequiresConfirm: config.skipRequiresConfirm,
autoFinishOnLastControl: config.autoFinishOnLastControl,
defaultControlScore: config.defaultControlScore,
},
settings: {
values: settings.values,
locks: settings.locks,
lockLifetimeActive,
},
telemetry: {
config: mergeTelemetrySources(config.telemetryConfig, playerTelemetryProfile),
playerProfile: playerTelemetryProfile,
},
presentation: {
course: config.courseStyleConfig,
track: config.trackStyleConfig,
gpsMarker: config.gpsMarkerStyleConfig,
},
feedback: {
audio: config.audioConfig,
haptics: config.hapticsConfig,
uiEffects: config.uiEffectsConfig,
},
}
}