using UnityEngine; public static class MapDatabase { private static MapDefinition[] maps; public static MapDefinition[] AllMaps { get { EnsureMaps(); return maps; } } public static MapDefinition GetMap(MapId mapId) { EnsureMaps(); for(int i = 0; i < maps.Length; i++) { if(maps[i].mapId == mapId) { return CloneMap(maps[i]); } } return CloneMap(maps[0]); } public static MapDefinition GetMapByIndex(int mapIndex) { EnsureMaps(); int clampedIndex = Mathf.Clamp(mapIndex, 0, maps.Length - 1); return CloneMap(maps[clampedIndex]); } public static int GetIndex(MapId mapId) { EnsureMaps(); for(int i = 0; i < maps.Length; i++) { if(maps[i].mapId == mapId) { return i; } } return 0; } public static int LastMapIndex { get { EnsureMaps(); return maps.Length - 1; } } private static void EnsureMaps() { if(maps != null && maps.Length > 0) { return; } maps = new MapDefinition[] { CreateTutorialIncheon(), CreateJapan(), CreateChina(), CreateAmerica() }; } private static MapDefinition CreateTutorialIncheon() { return new MapDefinition { mapId = MapId.TutorialIncheon, displayName = "Tutorial / Incheon", routeName = "인천공항 출발 준비", isTutorial = true, targetDistance = 850f, timeLimit = 95f, clearMileageReward = 150, hasNextMap = true, nextMapId = MapId.Japan, openingSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Jump, -2.4f, 1.05f, "점프", "가방 장애물이 보이면 왼쪽 클릭으로 뛰어넘습니다."), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.DoubleJump, -2.4f, 2.1f, "2단 점프", "다음 발판이 멀리 있으면 공중에서 한 번 더 왼쪽 클릭합니다."), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1.1f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, GameManager.TutorialGuideType.Slide, -2.4f, 1.15f, "슬라이드", "천장 표지판이 보이면 오른쪽 클릭을 누르고 지나갑니다."), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1f), Step(Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, GameManager.TutorialGuideType.Damage, -2.4f, 1.15f, "피격", "이번 구간은 일부러 맞아 목숨과 속도 감소를 확인합니다."), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Items, -2.4f, 0.95f, "초밥", "초밥을 먹으면 잃은 목숨을 1 회복합니다.", Platform.ItemPattern.HealthSushi), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Items, -2.4f, 0.9f, "라멘", "라멘을 먹고 다음 충돌을 피해 없이 지나가 봅니다.", Platform.ItemPattern.InvincibleRamen), Step(Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, GameManager.TutorialGuideType.None, -2.4f, 1.05f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Items, -2.4f, 0.9f, "방어막", "방어막을 먹고 다음 충돌 1회를 막아 봅니다.", Platform.ItemPattern.Shield), Step(Platform.PlatformPattern.ForceHit, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.WidePair, GameManager.TutorialGuideType.None, -2.4f, 1.05f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Items, -2.4f, 0.95f, "운동화", "운동화는 속도를 회복해 일정이 늦어지는 것을 줄입니다.", Platform.ItemPattern.SpeedShoes), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.Items, -2.4f, 0.95f, "마일리지 카드", "카드를 먹은 뒤 마일리지를 모으면 획득량이 늘어납니다.", Platform.ItemPattern.MileageCard), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1f) }, loopSteps = CreateEasyLoop() }; } private static MapDefinition CreateJapan() { return new MapDefinition { mapId = MapId.Japan, displayName = "Japan", routeName = "후쿠오카 라멘 투어", isTutorial = false, targetDistance = 1200f, timeLimit = 105f, clearMileageReward = 250, hasNextMap = true, nextMapId = MapId.China, openingSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.2f, 1.8f) }, loopSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.2f, 2.05f), Step(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.3f, 2.15f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, GameManager.TutorialGuideType.None, -2.25f, 2.35f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -1.95f, 2.05f), Step(Platform.PlatformPattern.LowLeft, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.35f, 2.1f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.WidePair, GameManager.TutorialGuideType.None, -2.3f, 2.45f) } }; } private static MapDefinition CreateChina() { return new MapDefinition { mapId = MapId.China, displayName = "China", routeName = "베이징 시장길", isTutorial = false, targetDistance = 1450f, timeLimit = 115f, clearMileageReward = 350, hasNextMap = true, nextMapId = MapId.America, openingSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.1f, 1.9f) }, loopSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.LowRight, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.25f, 2.0f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -1.8f, 2.05f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.LeftPair, GameManager.TutorialGuideType.None, -2.3f, 2.35f), Step(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 2.05f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.RightPair, GameManager.TutorialGuideType.None, -2.25f, 2.35f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2f, 1.95f) } }; } private static MapDefinition CreateAmerica() { return new MapDefinition { mapId = MapId.America, displayName = "America", routeName = "LA 공항 고속도로", isTutorial = false, targetDistance = 1700f, timeLimit = 125f, clearMileageReward = 500, hasNextMap = false, nextMapId = MapId.America, openingSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.2f, 1.8f) }, loopSteps = new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 1.95f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.WidePair, GameManager.TutorialGuideType.None, -2.25f, 2.25f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.None, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -1.8f, 1.9f), Step(Platform.PlatformPattern.LowLeft, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.35f, 1.95f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, GameManager.TutorialGuideType.None, -2.25f, 2.2f), Step(Platform.PlatformPattern.LowRight, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.1f, 1.9f) } }; } private static PlatformSpawner.TutorialStep[] CreateEasyLoop() { return new PlatformSpawner.TutorialStep[] { Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 2.1f), Step(Platform.PlatformPattern.LowMid, Platform.MileagePattern.JumpArc, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.4f, 2.2f), Step(Platform.PlatformPattern.Empty, Platform.MileagePattern.SafeLine, SlideObstaclePattern.SlideLayout.Random, GameManager.TutorialGuideType.None, -2.1f, 2.1f), Step(Platform.PlatformPattern.Slide, Platform.MileagePattern.SlideLine, SlideObstaclePattern.SlideLayout.CenterPair, GameManager.TutorialGuideType.None, -2.35f, 2.35f) }; } private static PlatformSpawner.TutorialStep Step( Platform.PlatformPattern platformPattern, Platform.MileagePattern mileagePattern, SlideObstaclePattern.SlideLayout slideLayout, GameManager.TutorialGuideType guideType, float yPosition, float spawnInterval, string title = "", string message = "", Platform.ItemPattern itemPattern = Platform.ItemPattern.None) { return new PlatformSpawner.TutorialStep { platformPattern = platformPattern, mileagePattern = mileagePattern, slideLayout = slideLayout, itemPattern = itemPattern, guideType = guideType, yPosition = yPosition, spawnInterval = spawnInterval, title = title, message = message }; } private static MapDefinition CloneMap(MapDefinition source) { return new MapDefinition { mapId = source.mapId, displayName = source.displayName, routeName = source.routeName, isTutorial = source.isTutorial, targetDistance = source.targetDistance, timeLimit = source.timeLimit, clearMileageReward = source.clearMileageReward, hasNextMap = source.hasNextMap, nextMapId = source.nextMapId, openingSteps = CloneSteps(source.openingSteps), loopSteps = CloneSteps(source.loopSteps) }; } public static PlatformSpawner.TutorialStep[] CloneSteps(PlatformSpawner.TutorialStep[] source) { if(source == null) { return new PlatformSpawner.TutorialStep[0]; } PlatformSpawner.TutorialStep[] steps = new PlatformSpawner.TutorialStep[source.Length]; for(int i = 0; i < source.Length; i++) { PlatformSpawner.TutorialStep sourceStep = source[i]; steps[i] = Step( sourceStep.platformPattern, sourceStep.mileagePattern, sourceStep.slideLayout, sourceStep.guideType, sourceStep.yPosition, sourceStep.spawnInterval, sourceStep.title, sourceStep.message, sourceStep.itemPattern); } return steps; } }