refactor(engine): 서비스 로직 정리
- ArenaService, PotionService, ProgressService 개선 - ResurrectionService, SkillService 정리
This commit is contained in:
@@ -104,8 +104,10 @@ class ProgressService {
|
||||
);
|
||||
|
||||
// ExpBar 초기화 (원본 743-746줄)
|
||||
final expBar =
|
||||
ProgressBarState(position: 0, max: ExpConstants.requiredExp(1));
|
||||
final expBar = ProgressBarState(
|
||||
position: 0,
|
||||
max: ExpConstants.requiredExp(1),
|
||||
);
|
||||
|
||||
// PlotBar 초기화 - Prologue 5분 (300초)
|
||||
final plotBar = const ProgressBarState(position: 0, max: 300);
|
||||
@@ -299,23 +301,40 @@ class ProgressService {
|
||||
progress = progress.copyWith(currentCombat: combatForReset);
|
||||
}
|
||||
|
||||
// 전투 상태 초기화, 몬스터 처치 수 증가 및 물약 사용 기록 초기화
|
||||
progress = progress.copyWith(
|
||||
currentCombat: null,
|
||||
monstersKilled: progress.monstersKilled + 1,
|
||||
);
|
||||
// Boss 승리 처리: 시네마틱 트리거
|
||||
if (progress.pendingActCompletion) {
|
||||
// Act Boss를 처치했으므로 시네마틱 재생
|
||||
final cinematicEntries = pq_logic.interplotCinematic(
|
||||
config,
|
||||
nextState.rng,
|
||||
nextState.traits.level,
|
||||
progress.plotStageCount,
|
||||
);
|
||||
queue = QueueState(entries: [...queue.entries, ...cinematicEntries]);
|
||||
progress = progress.copyWith(
|
||||
currentCombat: null,
|
||||
monstersKilled: progress.monstersKilled + 1,
|
||||
pendingActCompletion: false, // Boss 처치 완료
|
||||
);
|
||||
} else {
|
||||
// 일반 전투 종료
|
||||
progress = progress.copyWith(
|
||||
currentCombat: null,
|
||||
monstersKilled: progress.monstersKilled + 1,
|
||||
);
|
||||
}
|
||||
|
||||
final resetPotionInventory = nextState.potionInventory.resetBattleUsage();
|
||||
nextState = nextState.copyWith(
|
||||
progress: progress,
|
||||
queue: queue,
|
||||
potionInventory: resetPotionInventory,
|
||||
);
|
||||
|
||||
// 최종 보스 처치 체크
|
||||
if (progress.finalBossState == FinalBossState.fighting) {
|
||||
// 글리치 갓 처치 완료 - 게임 클리어
|
||||
progress = progress.copyWith(
|
||||
finalBossState: FinalBossState.defeated,
|
||||
);
|
||||
progress = progress.copyWith(finalBossState: FinalBossState.defeated);
|
||||
nextState = nextState.copyWith(progress: progress);
|
||||
|
||||
// completeAct를 호출하여 게임 완료 처리
|
||||
@@ -406,22 +425,22 @@ class ProgressService {
|
||||
}
|
||||
}
|
||||
|
||||
// 플롯(plot) 바가 완료되면 InterplotCinematic 트리거
|
||||
// (원본 Main.pas:1301-1304)
|
||||
// 플롯(plot) 바가 완료되면 Act Boss 소환
|
||||
// (개선: Boss 처치 → 시네마틱 → Act 전환 순서)
|
||||
if (gain &&
|
||||
progress.plot.max > 0 &&
|
||||
progress.plot.position >= progress.plot.max) {
|
||||
// InterplotCinematic을 호출하여 시네마틱 이벤트 큐에 추가
|
||||
final cinematicEntries = pq_logic.interplotCinematic(
|
||||
config,
|
||||
nextState.rng,
|
||||
nextState.traits.level,
|
||||
nextState.progress.plotStageCount,
|
||||
progress.plot.position >= progress.plot.max &&
|
||||
!progress.pendingActCompletion) {
|
||||
// Act Boss 소환 및 플래그 설정
|
||||
final actBoss = _createActBoss(nextState);
|
||||
progress = progress.copyWith(
|
||||
plot: progress.plot.copyWith(position: 0), // Plot bar 리셋
|
||||
currentCombat: actBoss,
|
||||
pendingActCompletion: true, // Boss 처치 대기 플래그
|
||||
);
|
||||
queue = QueueState(entries: [...queue.entries, ...cinematicEntries]);
|
||||
// 플롯 바를 0으로 리셋하지 않음 - completeAct에서 처리됨
|
||||
} else if (progress.currentTask.type != TaskType.load &&
|
||||
progress.plot.max > 0) {
|
||||
progress.plot.max > 0 &&
|
||||
!progress.pendingActCompletion) {
|
||||
final uncappedPlot = progress.plot.position + incrementSeconds;
|
||||
final int newPlotPos = uncappedPlot > progress.plot.max
|
||||
? progress.plot.max
|
||||
@@ -531,13 +550,44 @@ class ProgressService {
|
||||
return (progress: progress, queue: queue);
|
||||
}
|
||||
|
||||
// 3. 최종 보스 전투 체크
|
||||
// 3. Act Boss 리트라이 체크
|
||||
// pendingActCompletion이 true면 Act Boss 재소환
|
||||
if (state.progress.pendingActCompletion) {
|
||||
final actBoss = _createActBoss(state);
|
||||
final combatCalculator = CombatCalculator(rng: state.rng);
|
||||
final durationMillis = combatCalculator.estimateCombatDurationMs(
|
||||
player: actBoss.playerStats,
|
||||
monster: actBoss.monsterStats,
|
||||
);
|
||||
|
||||
final taskResult = pq_logic.startTask(
|
||||
progress,
|
||||
l10n.taskDebugging(actBoss.monsterStats.name),
|
||||
durationMillis,
|
||||
);
|
||||
|
||||
progress = taskResult.progress.copyWith(
|
||||
currentTask: TaskInfo(
|
||||
caption: taskResult.caption,
|
||||
type: TaskType.kill,
|
||||
monsterBaseName: actBoss.monsterStats.name,
|
||||
monsterPart: '*', // Boss는 WinItem 드랍
|
||||
monsterLevel: actBoss.monsterStats.level,
|
||||
monsterGrade: MonsterGrade.boss,
|
||||
),
|
||||
currentCombat: actBoss,
|
||||
);
|
||||
|
||||
return (progress: progress, queue: queue);
|
||||
}
|
||||
|
||||
// 4. 최종 보스 전투 체크
|
||||
// finalBossState == fighting이면 Glitch God 스폰
|
||||
if (state.progress.finalBossState == FinalBossState.fighting) {
|
||||
return _startFinalBossFight(state, progress, queue);
|
||||
}
|
||||
|
||||
// 4. MonsterTask 실행 (원본 678-684줄)
|
||||
// 5. MonsterTask 실행 (원본 678-684줄)
|
||||
final level = state.traits.level;
|
||||
|
||||
// 원본 Main.pas:548-551: 25% 확률로 Quest Monster 사용
|
||||
@@ -878,7 +928,8 @@ class ProgressService {
|
||||
var nextState = state;
|
||||
|
||||
// 현재 레벨이 목표 레벨보다 낮으면 레벨업 (최대 100레벨)
|
||||
while (nextState.traits.level < targetLevel && nextState.traits.level < 100) {
|
||||
while (nextState.traits.level < targetLevel &&
|
||||
nextState.traits.level < 100) {
|
||||
nextState = _levelUp(nextState);
|
||||
}
|
||||
|
||||
@@ -1390,10 +1441,13 @@ class ProgressService {
|
||||
|
||||
// 디버프 효과 추가 (기존 같은 디버프 제거 후)
|
||||
if (skillResult.debuffEffect != null) {
|
||||
activeDebuffs = activeDebuffs
|
||||
.where((d) => d.effect.id != skillResult.debuffEffect!.effect.id)
|
||||
.toList()
|
||||
..add(skillResult.debuffEffect!);
|
||||
activeDebuffs =
|
||||
activeDebuffs
|
||||
.where(
|
||||
(d) => d.effect.id != skillResult.debuffEffect!.effect.id,
|
||||
)
|
||||
.toList()
|
||||
..add(skillResult.debuffEffect!);
|
||||
}
|
||||
|
||||
// 디버프 이벤트 생성
|
||||
@@ -1533,6 +1587,55 @@ class ProgressService {
|
||||
);
|
||||
}
|
||||
|
||||
/// Act Boss 생성 (Act 완료 시)
|
||||
///
|
||||
/// 보스 레벨 = min(플레이어 레벨, Act 최소 레벨)로 설정하여
|
||||
/// 플레이어가 이길 수 있는 수준 보장
|
||||
CombatState _createActBoss(GameState state) {
|
||||
final plotStage = state.progress.plotStageCount;
|
||||
final actNumber = plotStage + 1;
|
||||
|
||||
// 보스 레벨 = min(플레이어 레벨, Act 최소 레벨)
|
||||
// → 플레이어가 현재 레벨보다 높은 보스를 만나지 않도록 보장
|
||||
final actMinLevel = ActMonsterLevel.forPlotStage(actNumber);
|
||||
final bossLevel = math.min(state.traits.level, actMinLevel);
|
||||
|
||||
// Named monster 생성 (pq_logic.namedMonster 활용)
|
||||
final bossName = pq_logic.namedMonster(config, state.rng, bossLevel);
|
||||
|
||||
final bossStats = MonsterBaseStats.forLevel(bossLevel);
|
||||
|
||||
// 플레이어 전투 스탯 생성
|
||||
final playerCombatStats = CombatStats.fromStats(
|
||||
stats: state.stats,
|
||||
equipment: state.equipment,
|
||||
level: state.traits.level,
|
||||
monsterLevel: bossLevel,
|
||||
);
|
||||
|
||||
// Boss 몬스터 스탯 생성 (일반 몬스터 대비 강화)
|
||||
final monsterCombatStats = MonsterCombatStats(
|
||||
name: bossName,
|
||||
level: bossLevel,
|
||||
atk: (bossStats.atk * 1.5).round(), // Boss 보정 (1.5배)
|
||||
def: (bossStats.def * 1.5).round(),
|
||||
hpMax: (bossStats.hp * 2.0).round(), // HP는 2.0배 (보스다운 전투 시간)
|
||||
hpCurrent: (bossStats.hp * 2.0).round(),
|
||||
criRate: 0.05,
|
||||
criDamage: 1.5,
|
||||
evasion: 0.0,
|
||||
accuracy: 0.8,
|
||||
attackDelayMs: 1000,
|
||||
expReward: (bossStats.exp * 2.5).round(), // 경험치 보상 증가
|
||||
);
|
||||
|
||||
// 전투 상태 초기화
|
||||
return CombatState.start(
|
||||
playerStats: playerCombatStats,
|
||||
monsterStats: monsterCombatStats,
|
||||
);
|
||||
}
|
||||
|
||||
/// 플레이어 사망 처리 (Phase 4)
|
||||
///
|
||||
/// 모든 장비 상실 및 사망 정보 기록
|
||||
@@ -1578,9 +1681,11 @@ class ProgressService {
|
||||
);
|
||||
|
||||
// 전투 상태 초기화 및 사망 횟수 증가
|
||||
// pendingActCompletion 플래그는 유지 (Boss 리트라이를 위해)
|
||||
final progress = state.progress.copyWith(
|
||||
currentCombat: null,
|
||||
deathCount: state.progress.deathCount + 1,
|
||||
// pendingActCompletion은 copyWith에서 명시하지 않으면 기존 값 유지
|
||||
);
|
||||
|
||||
return state.copyWith(
|
||||
|
||||
Reference in New Issue
Block a user