refactor(engine): ActProgressionService 및 UI 컨트롤러 분리
- ActProgressionService: Act 진행 로직 추출 - GameAudioController: 오디오 제어 로직 분리 - CombatLogController: 전투 로그 관리 분리 - ProgressService, GamePlayScreen 경량화
This commit is contained in:
262
lib/src/core/engine/act_progression_service.dart
Normal file
262
lib/src/core/engine/act_progression_service.dart
Normal file
@@ -0,0 +1,262 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
|
||||
import 'package:asciineverdie/src/core/engine/combat_calculator.dart';
|
||||
import 'package:asciineverdie/src/core/model/combat_state.dart';
|
||||
import 'package:asciineverdie/src/core/model/combat_stats.dart';
|
||||
import 'package:asciineverdie/src/core/model/game_state.dart';
|
||||
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
|
||||
import 'package:asciineverdie/src/core/model/monster_grade.dart';
|
||||
import 'package:asciineverdie/src/core/model/pq_config.dart';
|
||||
import 'package:asciineverdie/src/core/util/balance_constants.dart';
|
||||
import 'package:asciineverdie/src/core/util/pq_logic.dart' as pq_logic;
|
||||
|
||||
/// Act 진행 관련 로직을 처리하는 서비스
|
||||
///
|
||||
/// ProgressService에서 추출된 Act 완료, 보스 생성 등의 로직 담당.
|
||||
class ActProgressionService {
|
||||
const ActProgressionService({
|
||||
required this.config,
|
||||
});
|
||||
|
||||
final PqConfig config;
|
||||
|
||||
/// Act 완료 처리
|
||||
///
|
||||
/// 플롯 진행, Act Boss 시네마틱 후 호출.
|
||||
/// Returns gameComplete=true if Final Boss was defeated (game ends).
|
||||
({GameState state, bool gameComplete}) completeAct(GameState state) {
|
||||
// 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) {
|
||||
// 이미 최종 보스가 처치되었으면 게임 클리어
|
||||
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,
|
||||
);
|
||||
|
||||
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);
|
||||
var nextState = state;
|
||||
|
||||
// 보상 처리는 호출자(ProgressService)가 담당
|
||||
// 여기서는 플롯 상태만 업데이트
|
||||
|
||||
final plotStages = nextState.progress.plotStageCount + 1;
|
||||
|
||||
// 플롯 히스토리 업데이트: 이전 플롯 완료 표시, 새 플롯 추가
|
||||
final updatedPlotHistory = [
|
||||
...nextState.progress.plotHistory.map(
|
||||
(e) => e.isComplete ? e : e.copyWith(isComplete: true),
|
||||
),
|
||||
HistoryEntry(caption: actResult.actTitle, isComplete: false),
|
||||
];
|
||||
|
||||
var updatedProgress = nextState.progress.copyWith(
|
||||
plot: ProgressBarState(position: 0, max: actResult.plotBarMaxSeconds),
|
||||
plotStageCount: plotStages,
|
||||
plotHistory: updatedPlotHistory,
|
||||
);
|
||||
|
||||
nextState = nextState.copyWith(progress: updatedProgress);
|
||||
|
||||
// Act I 완료 후(Prologue -> Act I) 첫 퀘스트 시작 (원본 Main.pas 로직)
|
||||
// plotStages == 2는 Prologue(1) -> Act I(2) 전환을 의미
|
||||
if (plotStages == 2) {
|
||||
nextState = startFirstQuest(nextState);
|
||||
}
|
||||
|
||||
return (state: nextState, gameComplete: false);
|
||||
}
|
||||
|
||||
/// Act 완료 시 적용할 보상 목록 반환
|
||||
List<pq_logic.RewardKind> getActRewards(int plotStageCount) {
|
||||
final actResult = pq_logic.completeAct(plotStageCount);
|
||||
return actResult.rewards;
|
||||
}
|
||||
|
||||
/// 첫 퀘스트 시작 (Act I 시작 시)
|
||||
GameState startFirstQuest(GameState state) {
|
||||
final result = pq_logic.completeQuest(
|
||||
config,
|
||||
state.rng,
|
||||
state.traits.level,
|
||||
);
|
||||
|
||||
// 퀘스트 바 초기화
|
||||
final questBar = ProgressBarState(
|
||||
position: 0,
|
||||
max: 50 + state.rng.nextInt(100),
|
||||
);
|
||||
|
||||
// 첫 퀘스트 히스토리 추가
|
||||
final questHistory = [
|
||||
HistoryEntry(caption: result.caption, isComplete: false),
|
||||
];
|
||||
|
||||
// 퀘스트 몬스터 정보 저장 (Exterminate 타입용)
|
||||
final questMonster = result.monsterIndex != null
|
||||
? QuestMonsterInfo(
|
||||
monsterData: result.monsterName!,
|
||||
monsterIndex: result.monsterIndex!,
|
||||
)
|
||||
: null;
|
||||
|
||||
// 첫 퀘스트 추가
|
||||
final updatedQueue = QueueState(
|
||||
entries: [
|
||||
...state.queue.entries,
|
||||
QueueEntry(
|
||||
kind: QueueKind.task,
|
||||
durationMillis: 50 + state.rng.nextInt(100),
|
||||
caption: result.caption,
|
||||
taskType: TaskType.neutral,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
final progress = state.progress.copyWith(
|
||||
quest: questBar,
|
||||
questCount: 1,
|
||||
questHistory: questHistory,
|
||||
currentQuestMonster: questMonster,
|
||||
);
|
||||
|
||||
return state.copyWith(progress: progress, queue: updatedQueue);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
);
|
||||
}
|
||||
|
||||
/// 최종 보스(Glitch God) 전투 시작
|
||||
///
|
||||
/// Act V 플롯 완료 후 호출되며, 글리치 갓과의 전투를 설정합니다.
|
||||
({ProgressState progress, QueueState queue}) startFinalBossFight(
|
||||
GameState state,
|
||||
ProgressState progress,
|
||||
QueueState queue,
|
||||
) {
|
||||
final level = state.traits.level;
|
||||
|
||||
// Glitch God 생성 (레벨 100 최종 보스)
|
||||
final glitchGod = MonsterCombatStats.glitchGod();
|
||||
|
||||
// 플레이어 전투 스탯 생성 (Phase 12: 보스 레벨 기반 페널티 적용)
|
||||
final playerCombatStats = CombatStats.fromStats(
|
||||
stats: state.stats,
|
||||
equipment: state.equipment,
|
||||
level: level,
|
||||
monsterLevel: glitchGod.level,
|
||||
);
|
||||
|
||||
// 전투 상태 초기화
|
||||
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,
|
||||
monsterGrade: MonsterGrade.boss, // 최종 보스는 항상 boss 등급
|
||||
),
|
||||
currentCombat: combatState,
|
||||
);
|
||||
|
||||
return (progress: updatedProgress, queue: queue);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
|
||||
import 'package:asciineverdie/src/core/engine/act_progression_service.dart';
|
||||
import 'package:asciineverdie/src/core/engine/combat_calculator.dart';
|
||||
import 'package:asciineverdie/src/core/engine/combat_tick_service.dart';
|
||||
import 'package:asciineverdie/src/core/engine/game_mutations.dart';
|
||||
@@ -434,7 +435,8 @@ class ProgressService {
|
||||
progress.plot.position >= progress.plot.max &&
|
||||
!progress.pendingActCompletion) {
|
||||
// Act Boss 소환 및 플래그 설정
|
||||
final actBoss = _createActBoss(nextState);
|
||||
final actProgressionService = ActProgressionService(config: config);
|
||||
final actBoss = actProgressionService.createActBoss(nextState);
|
||||
progress = progress.copyWith(
|
||||
plot: progress.plot.copyWith(position: 0), // Plot bar 리셋
|
||||
currentCombat: actBoss,
|
||||
@@ -561,7 +563,8 @@ class ProgressService {
|
||||
// 3. Act Boss 리트라이 체크
|
||||
// pendingActCompletion이 true면 Act Boss 재소환
|
||||
if (state.progress.pendingActCompletion) {
|
||||
final actBoss = _createActBoss(state);
|
||||
final actProgressionService = ActProgressionService(config: config);
|
||||
final actBoss = actProgressionService.createActBoss(state);
|
||||
final combatCalculator = CombatCalculator(rng: state.rng);
|
||||
final durationMillis = combatCalculator.estimateCombatDurationMs(
|
||||
player: actBoss.playerStats,
|
||||
@@ -601,7 +604,8 @@ class ProgressService {
|
||||
if (state.progress.bossLevelingEndTime != null) {
|
||||
progress = progress.copyWith(clearBossLevelingEndTime: true);
|
||||
}
|
||||
return _startFinalBossFight(state, progress, queue);
|
||||
final actProgressionService = ActProgressionService(config: config);
|
||||
return actProgressionService.startFinalBossFight(state, progress, queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,63 +688,6 @@ 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;
|
||||
|
||||
// Glitch God 생성 (레벨 100 최종 보스)
|
||||
final glitchGod = MonsterCombatStats.glitchGod();
|
||||
|
||||
// 플레이어 전투 스탯 생성 (Phase 12: 보스 레벨 기반 페널티 적용)
|
||||
final playerCombatStats = CombatStats.fromStats(
|
||||
stats: state.stats,
|
||||
equipment: state.equipment,
|
||||
level: level,
|
||||
monsterLevel: glitchGod.level,
|
||||
);
|
||||
|
||||
// 전투 상태 초기화
|
||||
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,
|
||||
monsterGrade: MonsterGrade.boss, // 최종 보스는 항상 boss 등급
|
||||
),
|
||||
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(
|
||||
@@ -801,127 +748,24 @@ class ProgressService {
|
||||
/// Advances plot to next act and applies any act-level rewards.
|
||||
/// Returns gameComplete=true if Final Boss was defeated (game ends).
|
||||
({GameState state, bool gameComplete}) completeAct(GameState state) {
|
||||
// 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) {
|
||||
// 이미 최종 보스가 처치되었으면 게임 클리어
|
||||
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 actProgressionService = ActProgressionService(config: config);
|
||||
|
||||
final updatedProgress = state.progress.copyWith(
|
||||
plotHistory: updatedPlotHistory,
|
||||
);
|
||||
|
||||
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);
|
||||
// Act 보상 먼저 적용
|
||||
final actRewards = actProgressionService.getActRewards(
|
||||
state.progress.plotStageCount,
|
||||
);
|
||||
var nextState = state;
|
||||
for (final reward in actResult.rewards) {
|
||||
for (final reward in actRewards) {
|
||||
nextState = _applyReward(nextState, reward);
|
||||
}
|
||||
|
||||
final plotStages = nextState.progress.plotStageCount + 1;
|
||||
// Act 완료 처리 (ActProgressionService 위임)
|
||||
final result = actProgressionService.completeAct(nextState);
|
||||
|
||||
// 플롯 히스토리 업데이트: 이전 플롯 완료 표시, 새 플롯 추가
|
||||
final updatedPlotHistory = [
|
||||
...nextState.progress.plotHistory.map(
|
||||
(e) => e.isComplete ? e : e.copyWith(isComplete: true),
|
||||
),
|
||||
HistoryEntry(caption: actResult.actTitle, isComplete: false),
|
||||
];
|
||||
|
||||
var updatedProgress = nextState.progress.copyWith(
|
||||
plot: ProgressBarState(position: 0, max: actResult.plotBarMaxSeconds),
|
||||
plotStageCount: plotStages,
|
||||
plotHistory: updatedPlotHistory,
|
||||
return (
|
||||
state: _recalculateEncumbrance(result.state),
|
||||
gameComplete: result.gameComplete,
|
||||
);
|
||||
|
||||
nextState = nextState.copyWith(progress: updatedProgress);
|
||||
|
||||
// Act I 완료 후(Prologue -> Act I) 첫 퀘스트 시작 (원본 Main.pas 로직)
|
||||
// plotStages == 2는 Prologue(1) -> Act I(2) 전환을 의미
|
||||
if (plotStages == 2) {
|
||||
nextState = _startFirstQuest(nextState);
|
||||
}
|
||||
|
||||
return (state: _recalculateEncumbrance(nextState), gameComplete: false);
|
||||
}
|
||||
|
||||
/// 첫 퀘스트 시작 (Act I 시작 시)
|
||||
GameState _startFirstQuest(GameState state) {
|
||||
final result = pq_logic.completeQuest(
|
||||
config,
|
||||
state.rng,
|
||||
state.traits.level,
|
||||
);
|
||||
|
||||
// 퀘스트 바 초기화
|
||||
final questBar = ProgressBarState(
|
||||
position: 0,
|
||||
max: 50 + state.rng.nextInt(100),
|
||||
);
|
||||
|
||||
// 첫 퀘스트 히스토리 추가
|
||||
final questHistory = [
|
||||
HistoryEntry(caption: result.caption, isComplete: false),
|
||||
];
|
||||
|
||||
// 퀘스트 몬스터 정보 저장 (Exterminate 타입용)
|
||||
// 원본 fQuest.Caption = monsterData, fQuest.Tag = monsterIndex
|
||||
final questMonster = result.monsterIndex != null
|
||||
? QuestMonsterInfo(
|
||||
monsterData: result.monsterName!,
|
||||
monsterIndex: result.monsterIndex!,
|
||||
)
|
||||
: null;
|
||||
|
||||
// 첫 퀘스트 추가
|
||||
final updatedQueue = QueueState(
|
||||
entries: [
|
||||
...state.queue.entries,
|
||||
QueueEntry(
|
||||
kind: QueueKind.task,
|
||||
durationMillis: 50 + state.rng.nextInt(100),
|
||||
caption: result.caption,
|
||||
taskType: TaskType.neutral,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
final progress = state.progress.copyWith(
|
||||
quest: questBar,
|
||||
questCount: 1,
|
||||
questHistory: questHistory,
|
||||
currentQuestMonster: questMonster,
|
||||
);
|
||||
|
||||
return state.copyWith(progress: progress, queue: updatedQueue);
|
||||
}
|
||||
|
||||
/// Developer-only cheat hooks for quickly finishing bars.
|
||||
@@ -1096,55 +940,6 @@ class ProgressService {
|
||||
return s[0].toUpperCase() + s.substring(1);
|
||||
}
|
||||
|
||||
/// 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)
|
||||
///
|
||||
/// 모든 장비 상실 및 사망 정보 기록
|
||||
|
||||
Reference in New Issue
Block a user