refactor(core): 진행 서비스 및 모델 개선

- ProgressService 로직 개선
- GameState 상태 관리 확장
- MonsterCombatStats 속성 추가
- game_text_l10n 번역 추가
This commit is contained in:
JiWoong Sul
2026-01-02 15:30:09 +09:00
parent c9f0e35914
commit 2ef9807cbe
4 changed files with 165 additions and 18 deletions

View File

@@ -302,6 +302,27 @@ class ProgressService {
progress: progress,
potionInventory: resetPotionInventory,
);
// 최종 보스 처치 체크
if (progress.finalBossState == FinalBossState.fighting) {
// 글리치 갓 처치 완료 - 게임 클리어
progress = progress.copyWith(
finalBossState: FinalBossState.defeated,
);
nextState = nextState.copyWith(progress: progress);
// completeAct를 호출하여 게임 완료 처리
final actResult = completeAct(nextState);
nextState = actResult.state;
return ProgressTickResult(
state: nextState,
leveledUp: false,
completedQuest: false,
completedAct: true,
gameComplete: true,
);
}
}
// 시장/판매/구매 태스크 완료 시 처리 (원본 Main.pas:631-649)
@@ -494,7 +515,13 @@ class ProgressService {
return (progress: progress, queue: queue);
}
// 3. MonsterTask 실행 (원본 678-684줄)
// 3. 최종 보스 전투 체크
// finalBossState == fighting이면 Glitch God 스폰
if (state.progress.finalBossState == FinalBossState.fighting) {
return _startFinalBossFight(state, progress, queue);
}
// 4. MonsterTask 실행 (원본 678-684줄)
final level = state.traits.level;
// 원본 Main.pas:548-551: 25% 확률로 Quest Monster 사용
@@ -567,6 +594,61 @@ class ProgressService {
return (progress: progress, queue: queue);
}
/// 최종 보스(Glitch God) 전투 시작
///
/// Act V 플롯 완료 후 호출되며, 글리치 갓과의 전투를 설정합니다.
({ProgressState progress, QueueState queue}) _startFinalBossFight(
GameState state,
ProgressState progress,
QueueState queue,
) {
final level = state.traits.level;
// 플레이어 전투 스탯 생성
final playerCombatStats = CombatStats.fromStats(
stats: state.stats,
equipment: state.equipment,
level: level,
);
// Glitch God 생성 (레벨 100 최종 보스)
final glitchGod = MonsterCombatStats.glitchGod();
// 전투 상태 초기화
final combatState = CombatState.start(
playerStats: playerCombatStats,
monsterStats: glitchGod,
);
// 전투 시간 추정 (보스 전투는 더 길게)
final combatCalculator = CombatCalculator(rng: state.rng);
final baseDuration = combatCalculator.estimateCombatDurationMs(
player: playerCombatStats,
monster: glitchGod,
);
// 최종 보스는 최소 10초, 최대 60초
final durationMillis = baseDuration.clamp(10000, 60000);
final taskResult = pq_logic.startTask(
progress,
l10n.taskFinalBoss(glitchGod.name),
durationMillis,
);
final updatedProgress = taskResult.progress.copyWith(
currentTask: TaskInfo(
caption: taskResult.caption,
type: TaskType.kill,
monsterBaseName: 'Glitch God',
monsterPart: '*', // 특수 전리품
monsterLevel: glitchGod.level,
),
currentCombat: combatState,
);
return (progress: updatedProgress, queue: queue);
}
/// Advances quest completion, applies reward, and enqueues next quest task.
GameState completeQuest(GameState state) {
final result = pq_logic.completeQuest(
@@ -625,28 +707,45 @@ class ProgressService {
}
/// Advances plot to next act and applies any act-level rewards.
/// Returns gameComplete=true if Act V was completed (game ends).
/// Returns gameComplete=true if Final Boss was defeated (game ends).
({GameState state, bool gameComplete}) completeAct(GameState state) {
// Act V 완료 시 (plotStageCount == 6) 게임 클리어
// Act V 완료 시 (plotStageCount == 6) → 최종 보스 전투 시작
// plotStageCount: 1=Prologue, 2=Act I, 3=Act II, 4=Act III, 5=Act IV, 6=Act V
if (state.progress.plotStageCount >= 6) {
// Act V 완료 - 게임 클리어!
// 히스토리만 업데이트하고 새 Act는 생성하지 않음
final updatedPlotHistory = [
...state.progress.plotHistory.map(
(e) => e.isComplete ? e : e.copyWith(isComplete: true),
),
const HistoryEntry(caption: '*** THE END ***', isComplete: true),
];
// 이미 최종 보스가 처치되었으면 게임 클리어
if (state.progress.finalBossState == FinalBossState.defeated) {
final updatedPlotHistory = [
...state.progress.plotHistory.map(
(e) => e.isComplete ? e : e.copyWith(isComplete: true),
),
const HistoryEntry(caption: '*** THE END ***', isComplete: true),
];
final updatedProgress = state.progress.copyWith(
plotHistory: updatedPlotHistory,
);
final updatedProgress = state.progress.copyWith(
plotHistory: updatedPlotHistory,
);
return (
state: state.copyWith(progress: updatedProgress),
gameComplete: true,
);
return (
state: state.copyWith(progress: updatedProgress),
gameComplete: true,
);
}
// 최종 보스가 아직 등장하지 않았으면 보스 전투 시작
if (state.progress.finalBossState == FinalBossState.notSpawned) {
final updatedProgress = state.progress.copyWith(
finalBossState: FinalBossState.fighting,
);
// 게임은 아직 끝나지 않음 - 보스 전투 진행
return (
state: state.copyWith(progress: updatedProgress),
gameComplete: false,
);
}
// 보스 전투 중이면 계속 진행 (게임 종료 안 함)
return (state: state, gameComplete: false);
}
final actResult = pq_logic.completeAct(state.progress.plotStageCount);