diff --git a/lib/src/core/engine/progress_service.dart b/lib/src/core/engine/progress_service.dart index 904156a..ed918e4 100644 --- a/lib/src/core/engine/progress_service.dart +++ b/lib/src/core/engine/progress_service.dart @@ -355,12 +355,14 @@ class ProgressService { } // Gain XP / level up. + // 최대 레벨(100) 제한: 100레벨에서는 더 이상 레벨업하지 않음 if (gain) { - if (progress.exp.position >= progress.exp.max) { + if (progress.exp.position >= progress.exp.max && + nextState.traits.level < 100) { nextState = _levelUp(nextState); leveledUp = true; progress = nextState.progress; - } else { + } else if (nextState.traits.level < 100) { final uncappedExp = progress.exp.position + incrementSeconds; final int newExpPos = uncappedExp > progress.exp.max ? progress.exp.max @@ -863,8 +865,8 @@ class ProgressService { final targetLevel = ActMonsterLevel.forPlotStage(nextPlotStage); var nextState = state; - // 현재 레벨이 목표 레벨보다 낮으면 레벨업 - while (nextState.traits.level < targetLevel) { + // 현재 레벨이 목표 레벨보다 낮으면 레벨업 (최대 100레벨) + while (nextState.traits.level < targetLevel && nextState.traits.level < 100) { nextState = _levelUp(nextState); } @@ -885,6 +887,11 @@ class ProgressService { } GameState _levelUp(GameState state) { + // 최대 레벨(100) 안전장치: 이미 100레벨이면 레벨업하지 않음 + if (state.traits.level >= 100) { + return state; + } + final nextLevel = state.traits.level + 1; final rng = state.rng; final hpGain = state.stats.con ~/ 3 + 1 + rng.nextInt(4); diff --git a/lib/src/core/util/balance_constants.dart b/lib/src/core/util/balance_constants.dart index 5a948dc..b91a07a 100644 --- a/lib/src/core/util/balance_constants.dart +++ b/lib/src/core/util/balance_constants.dart @@ -159,14 +159,14 @@ class MonsterBaseStats { /// 레벨 기반 기본 스탯 생성 /// /// HP: 50 + level * 20 + (level^2 / 5) - /// ATK: 3 + level * 2 (초반 생존율 개선을 위해 약화) + /// ATK: 5 + level * 4 (플레이어 DEF 스케일링에 맞춰 상향) /// DEF: 2 + level * 2 /// EXP: 10 + level * 5 /// GOLD: 5 + level * 3 factory MonsterBaseStats.forLevel(int level) { return MonsterBaseStats( hp: 50 + level * 20 + (level * level ~/ 5), - atk: 3 + level * 2, + atk: 5 + level * 4, def: 2 + level * 2, exp: 10 + level * 5, gold: 5 + level * 3, diff --git a/lib/src/core/util/pq_logic.dart b/lib/src/core/util/pq_logic.dart index 9d175cc..90063e9 100644 --- a/lib/src/core/util/pq_logic.dart +++ b/lib/src/core/util/pq_logic.dart @@ -71,10 +71,25 @@ class ItemResult { } int levelUpTimeSeconds(int level) { - // 10시간 내 레벨 100 도달 목표 (선형 성장) - // 레벨 1: ~2분, 레벨 100: ~7분 - final seconds = 120 + (level * 3); - return seconds; + // Act 진행과 레벨업 동기화 (10시간 완주 목표) + // Act I 끝(2시간): 레벨 20, Act II 끝(5시간): 레벨 40, etc. + // 레벨 1: ~5분, 레벨 50: ~7분, 레벨 100: ~4분 (후반 가속) + if (level <= 20) { + // Act I: 레벨 1-20, 2시간 (7200초) → 평균 360초/레벨 + return 300 + (level * 6); + } else if (level <= 40) { + // Act II: 레벨 21-40, 3시간 (10800초) → 평균 540초/레벨 + return 400 + ((level - 20) * 10); + } else if (level <= 60) { + // Act III: 레벨 41-60, 3시간 (10800초) → 평균 540초/레벨 + return 400 + ((level - 40) * 10); + } else if (level <= 80) { + // Act IV: 레벨 61-80, 1.5시간 (5400초) → 평균 270초/레벨 + return 200 + ((level - 60) * 5); + } else { + // Act V: 레벨 81-100, 30분 (1800초) → 평균 90초/레벨 + return 60 + ((level - 80) * 3); + } } /// 초 단위 시간을 사람이 읽기 쉬운 형태로 변환 (원본 Main.pas:1265-1271)