runtimeProfileCompiler.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { type RemoteMapConfig } from '../../utils/remoteMapConfig'
  2. import { type GameAudioConfig } from '../audio/audioConfig'
  3. import { type GameHapticsConfig, type GameUiEffectsConfig } from '../feedback/feedbackConfig'
  4. import { getGameModeDefaults } from './gameModeDefaults'
  5. import {
  6. resolveSystemSettingsState,
  7. type ResolvedSystemSettingsState,
  8. } from './systemSettingsState'
  9. import { type CourseStyleConfig } from '../presentation/courseStyleConfig'
  10. import { type GpsMarkerStyleConfig } from '../presentation/gpsMarkerStyleConfig'
  11. import { type TrackVisualizationConfig } from '../presentation/trackStyleConfig'
  12. import { mergeTelemetrySources, type PlayerTelemetryProfile } from '../telemetry/playerTelemetryProfile'
  13. import { type TelemetryConfig } from '../telemetry/telemetryConfig'
  14. export interface RuntimeMapProfile {
  15. title: string
  16. tileSource: string
  17. projectionModeText: string
  18. magneticDeclinationText: string
  19. cpRadiusMeters: number
  20. projection: string
  21. magneticDeclinationDeg: number
  22. minZoom: number
  23. maxZoom: number
  24. initialZoom: number
  25. initialCenterTileX: number
  26. initialCenterTileY: number
  27. tileBoundsByZoom: RemoteMapConfig['tileBoundsByZoom']
  28. courseStatusText: string
  29. }
  30. export interface RuntimeGameProfile {
  31. mode: RemoteMapConfig['gameMode']
  32. sessionCloseAfterMs: number
  33. sessionCloseWarningMs: number
  34. minCompletedControlsBeforeFinish: number
  35. punchPolicy: RemoteMapConfig['punchPolicy']
  36. punchRadiusMeters: number
  37. requiresFocusSelection: boolean
  38. skipEnabled: boolean
  39. skipRadiusMeters: number
  40. skipRequiresConfirm: boolean
  41. autoFinishOnLastControl: boolean
  42. defaultControlScore: number | null
  43. }
  44. export interface RuntimePresentationProfile {
  45. course: CourseStyleConfig
  46. track: TrackVisualizationConfig
  47. gpsMarker: GpsMarkerStyleConfig
  48. }
  49. export interface RuntimeFeedbackProfile {
  50. audio: GameAudioConfig
  51. haptics: GameHapticsConfig
  52. uiEffects: GameUiEffectsConfig
  53. }
  54. export interface RuntimeTelemetryProfile {
  55. config: TelemetryConfig
  56. playerProfile: PlayerTelemetryProfile | null
  57. }
  58. export interface RuntimeSettingsProfile extends ResolvedSystemSettingsState {
  59. lockLifetimeActive: boolean
  60. }
  61. export interface CompiledRuntimeProfile {
  62. map: RuntimeMapProfile
  63. game: RuntimeGameProfile
  64. settings: RuntimeSettingsProfile
  65. telemetry: RuntimeTelemetryProfile
  66. presentation: RuntimePresentationProfile
  67. feedback: RuntimeFeedbackProfile
  68. }
  69. export interface CompileRuntimeProfileOptions {
  70. playerTelemetryProfile?: PlayerTelemetryProfile | null
  71. settingsLockLifetimeActive?: boolean
  72. storedSettingsKey?: string
  73. }
  74. export function compileRuntimeProfile(
  75. config: RemoteMapConfig,
  76. options?: CompileRuntimeProfileOptions,
  77. ): CompiledRuntimeProfile {
  78. const modeDefaults = getGameModeDefaults(config.gameMode)
  79. const lockLifetimeActive = !!(options && options.settingsLockLifetimeActive === true)
  80. const playerTelemetryProfile = options && options.playerTelemetryProfile
  81. ? Object.assign({}, options.playerTelemetryProfile)
  82. : null
  83. const settings = resolveSystemSettingsState(
  84. config.systemSettingsConfig,
  85. options && options.storedSettingsKey ? options.storedSettingsKey : undefined,
  86. lockLifetimeActive,
  87. )
  88. return {
  89. map: {
  90. title: config.configTitle,
  91. tileSource: config.tileSource,
  92. projectionModeText: config.projectionModeText,
  93. magneticDeclinationText: config.magneticDeclinationText,
  94. cpRadiusMeters: config.cpRadiusMeters,
  95. projection: config.projection,
  96. magneticDeclinationDeg: config.magneticDeclinationDeg,
  97. minZoom: config.minZoom,
  98. maxZoom: config.maxZoom,
  99. initialZoom: config.defaultZoom,
  100. initialCenterTileX: config.initialCenterTileX,
  101. initialCenterTileY: config.initialCenterTileY,
  102. tileBoundsByZoom: config.tileBoundsByZoom,
  103. courseStatusText: config.courseStatusText,
  104. },
  105. game: {
  106. mode: config.gameMode,
  107. sessionCloseAfterMs: config.sessionCloseAfterMs || modeDefaults.sessionCloseAfterMs,
  108. sessionCloseWarningMs: config.sessionCloseWarningMs || modeDefaults.sessionCloseWarningMs,
  109. minCompletedControlsBeforeFinish: config.minCompletedControlsBeforeFinish,
  110. punchPolicy: config.punchPolicy,
  111. punchRadiusMeters: config.punchRadiusMeters,
  112. requiresFocusSelection: config.requiresFocusSelection,
  113. skipEnabled: config.skipEnabled,
  114. skipRadiusMeters: config.skipRadiusMeters,
  115. skipRequiresConfirm: config.skipRequiresConfirm,
  116. autoFinishOnLastControl: config.autoFinishOnLastControl,
  117. defaultControlScore: config.defaultControlScore,
  118. },
  119. settings: {
  120. values: settings.values,
  121. locks: settings.locks,
  122. lockLifetimeActive,
  123. },
  124. telemetry: {
  125. config: mergeTelemetrySources(config.telemetryConfig, playerTelemetryProfile),
  126. playerProfile: playerTelemetryProfile,
  127. },
  128. presentation: {
  129. course: config.courseStyleConfig,
  130. track: config.trackStyleConfig,
  131. gpsMarker: config.gpsMarkerStyleConfig,
  132. },
  133. feedback: {
  134. audio: config.audioConfig,
  135. haptics: config.hapticsConfig,
  136. uiEffects: config.uiEffectsConfig,
  137. },
  138. }
  139. }