feat(core): 엔진, 모델, 애니메이션 개선
- ProgressService 로직 개선 - CombatCalculator 업데이트 - GameState, MonsterCombatStats 확장 - CanvasBattleComposer 개선
This commit is contained in:
@@ -475,7 +475,8 @@ class Inventory {
|
||||
final int gold;
|
||||
final List<InventoryEntry> items;
|
||||
|
||||
factory Inventory.empty() => const Inventory(gold: 0, items: []);
|
||||
/// 초기 골드 1000 지급 (캐릭터 생성 시)
|
||||
factory Inventory.empty() => const Inventory(gold: 1000, items: []);
|
||||
|
||||
Inventory copyWith({int? gold, List<InventoryEntry>? items}) {
|
||||
return Inventory(gold: gold ?? this.gold, items: items ?? this.items);
|
||||
@@ -800,6 +801,7 @@ class ProgressState {
|
||||
this.deathCount = 0,
|
||||
this.finalBossState = FinalBossState.notSpawned,
|
||||
this.pendingActCompletion = false,
|
||||
this.bossLevelingEndTime,
|
||||
});
|
||||
|
||||
final ProgressBarState task;
|
||||
@@ -835,6 +837,10 @@ class ProgressState {
|
||||
/// Act Boss 처치 대기 중 여부 (처치 후 시네마틱 재생 트리거)
|
||||
final bool pendingActCompletion;
|
||||
|
||||
/// 보스 사망 후 레벨링 모드 종료 시간 (milliseconds since epoch)
|
||||
/// null이면 레벨링 모드 아님, 값이 있으면 해당 시간까지 레벨링
|
||||
final int? bossLevelingEndTime;
|
||||
|
||||
factory ProgressState.empty() => ProgressState(
|
||||
task: ProgressBarState.empty(),
|
||||
quest: ProgressBarState.empty(),
|
||||
@@ -867,6 +873,8 @@ class ProgressState {
|
||||
int? deathCount,
|
||||
FinalBossState? finalBossState,
|
||||
bool? pendingActCompletion,
|
||||
int? bossLevelingEndTime,
|
||||
bool clearBossLevelingEndTime = false,
|
||||
}) {
|
||||
return ProgressState(
|
||||
task: task ?? this.task,
|
||||
@@ -885,8 +893,17 @@ class ProgressState {
|
||||
deathCount: deathCount ?? this.deathCount,
|
||||
finalBossState: finalBossState ?? this.finalBossState,
|
||||
pendingActCompletion: pendingActCompletion ?? this.pendingActCompletion,
|
||||
bossLevelingEndTime: clearBossLevelingEndTime
|
||||
? null
|
||||
: (bossLevelingEndTime ?? this.bossLevelingEndTime),
|
||||
);
|
||||
}
|
||||
|
||||
/// 현재 레벨링 모드인지 확인
|
||||
bool get isInBossLevelingMode {
|
||||
if (bossLevelingEndTime == null) return false;
|
||||
return DateTime.now().millisecondsSinceEpoch < bossLevelingEndTime!;
|
||||
}
|
||||
}
|
||||
|
||||
class QueueEntry {
|
||||
|
||||
@@ -131,15 +131,29 @@ class MonsterCombatStats {
|
||||
/// [level] 몬스터 레벨 (원본 데이터 기준)
|
||||
/// [speedType] 공격 속도 타입 (기본: normal)
|
||||
/// [monsterType] 몬스터 타입 (기본: normal)
|
||||
/// [plotStageCount] 현재 Act (1=Prologue, 2=Act I, 3=Act II, ...)
|
||||
factory MonsterCombatStats.fromLevel({
|
||||
required String name,
|
||||
required int level,
|
||||
MonsterSpeedType speedType = MonsterSpeedType.normal,
|
||||
MonsterType monsterType = MonsterType.normal,
|
||||
int plotStageCount = 1,
|
||||
}) {
|
||||
// balance_constants.dart의 MonsterBaseStats 사용
|
||||
final baseStats = MonsterBaseStats.generate(level, monsterType);
|
||||
|
||||
// Act II 이후 (plotStageCount >= 3) HP 10% 상승
|
||||
final hpMultiplier = plotStageCount >= 3 ? 1.1 : 1.0;
|
||||
final adjustedHp = (baseStats.hp * hpMultiplier).round();
|
||||
|
||||
// Act별 경험치 배율 (후반부 레벨업 가속)
|
||||
final expMultiplier = switch (plotStageCount) {
|
||||
5 => 1.3, // Act IV: 30% 보너스
|
||||
6 => 1.8, // Act V: 80% 보너스 (보스전 대비)
|
||||
_ => 1.0, // 기본
|
||||
};
|
||||
final adjustedExp = (baseStats.exp * expMultiplier).round();
|
||||
|
||||
// 크리티컬 확률: 레벨에 따라 천천히 증가 (0.02 ~ 0.3)
|
||||
final criRate = (0.02 + level * 0.003).clamp(0.02, 0.3);
|
||||
|
||||
@@ -164,14 +178,14 @@ class MonsterCombatStats {
|
||||
level: level,
|
||||
atk: baseStats.atk,
|
||||
def: baseStats.def,
|
||||
hpMax: baseStats.hp,
|
||||
hpCurrent: baseStats.hp,
|
||||
hpMax: adjustedHp,
|
||||
hpCurrent: adjustedHp,
|
||||
criRate: criRate,
|
||||
criDamage: criDamage,
|
||||
evasion: evasion,
|
||||
accuracy: accuracy,
|
||||
attackDelayMs: attackDelayMs,
|
||||
expReward: baseStats.exp,
|
||||
expReward: adjustedExp,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user