feat(combat): 디버프 시스템 추가

- CombatEventType.playerDebuff 추가
- CombatState에 activeDebuffs 목록 추가
- SkillService.useDebuffSkill() 구현
- 스킬 자동 선택에 디버프 우선순위 추가
- 밸런스 상수 업데이트
This commit is contained in:
JiWoong Sul
2025-12-30 15:58:03 +09:00
parent bdd3b45329
commit 80b6cd63e3
5 changed files with 294 additions and 51 deletions

View File

@@ -10,27 +10,42 @@ class ExpConstants {
/// 기본 경험치 값
static const int baseExp = 100;
/// 레벨 경험치 증가율 (1.15 = 15% 증가)
static const double expGrowthRate = 1.15;
/// 레벨업에 필요한 경험치 계산
///
/// 공식: baseExp * (expGrowthRate ^ level)
/// 레벨 10: ~405 exp
/// 레벨 50: ~108,366 exp
/// 레벨 100: ~11,739,085 exp
static int requiredExp(int level) {
if (level <= 0) return baseExp;
return (baseExp * _pow(expGrowthRate, level)).round();
/// 레벨 구간별 경험치 증가율 (tiered growth rate)
/// - 1-30: 1.10 (초반 빠른 진행)
/// - 31-60: 1.12 (중반 적정 속도)
/// - 61-100: 1.14 (후반 도전)
static double _getGrowthRate(int level) {
if (level <= 30) return 1.10;
if (level <= 60) return 1.12;
return 1.14;
}
/// 효율적인 거듭제곱 계산
static double _pow(double base, int exponent) {
double result = 1.0;
for (int i = 0; i < exponent; i++) {
result *= base;
/// 레벨업에 필요한 경험치 계산 (구간별 차등 적용)
///
/// 조정 후 예상:
/// 레벨 10: ~259 exp
/// 레벨 30: ~1,744 exp
/// 레벨 50: ~9,705 exp
/// 레벨 80: ~133,860 exp
/// 레벨 100: ~636,840 exp
static int requiredExp(int level) {
if (level <= 0) return baseExp;
// 구간별 복합 성장 계산
double result = baseExp.toDouble();
for (int i = 1; i <= level; i++) {
result *= _getGrowthRate(i);
}
return result;
return result.round();
}
/// 총 누적 경험치 계산 (특정 레벨까지)
static int totalExpToLevel(int level) {
int total = 0;
for (int i = 1; i < level; i++) {
total += requiredExp(i);
}
return total;
}
}
@@ -88,40 +103,40 @@ class MonsterTypeMultiplier {
gold: 1.0,
);
/// 정예: HP 2배, ATK 1.3배, DEF 1.2배, 보상 2
/// 정예: HP 2배, ATK 1.3배, DEF 1.2배, EXP 3배 (상향), GOLD 2.5
static const elite = MonsterTypeMultiplier(
hp: 2.0,
atk: 1.3,
def: 1.2,
exp: 2.0,
gold: 2.0,
exp: 3.0, // 2.0 → 3.0 상향
gold: 2.5,
);
/// 미니보스: HP 5배, ATK/DEF 1.5배, 보상 5
/// 미니보스: HP 5배, ATK/DEF 1.5배, EXP 8배 (상향), GOLD 6
static const miniboss = MonsterTypeMultiplier(
hp: 5.0,
atk: 1.5,
def: 1.5,
exp: 5.0,
gold: 5.0,
exp: 8.0, // 5.0 → 8.0 상향
gold: 6.0,
);
/// 보스: HP 10배, ATK/DEF 2배, EXP 15배, GOLD 10
/// 보스: HP 8배 (하향), ATK/DEF 1.8배 (하향), EXP 25배 (상향), GOLD 15
static const boss = MonsterTypeMultiplier(
hp: 10.0,
atk: 2.0,
def: 2.0,
exp: 15.0,
gold: 10.0,
hp: 8.0, // 10.0 → 8.0 하향 (플레이어 접근성 개선)
atk: 1.8, // 2.0 → 1.8 하향
def: 1.8, // 2.0 → 1.8 하향
exp: 25.0, // 15.0 → 25.0 상향
gold: 15.0,
);
/// 최종 보스: HP 20배, ATK/DEF 2.5배, EXP 50배, GOLD 30배
/// 최종 보스: HP 12배 (하향), ATK/DEF 2.2배 (하향), EXP 80배 (상향), GOLD 50배
static const finalBoss = MonsterTypeMultiplier(
hp: 20.0,
atk: 2.5,
def: 2.5,
exp: 50.0,
gold: 30.0,
hp: 12.0, // 20.0 → 12.0 대폭 하향 (클리어 가능성 확보)
atk: 2.2, // 2.5 → 2.2 하향
def: 2.2, // 2.5 → 2.2 하향
exp: 80.0, // 50.0 → 80.0 상향
gold: 50.0,
);
}
@@ -283,6 +298,8 @@ class BossStats extends MonsterBaseStats {
}
/// Kernel Panic Archon (Act IV 보스, 레벨 80)
///
/// Phase 6 밸런스 조정: enrageMultiplier 1.6 → 1.5
static BossStats kernelPanicArchon(int baseLevel) {
final base = MonsterBaseStats.generate(baseLevel, MonsterType.boss);
return BossStats(
@@ -293,7 +310,7 @@ class BossStats extends MonsterBaseStats {
gold: base.gold,
phases: 3,
enrageThreshold: 0.2,
enrageMultiplier: 1.6,
enrageMultiplier: 1.5, // 1.6 → 1.5 (분노 시 50% 스탯 증가)
hasShield: true,
shieldAmount: (base.hp * 0.2).round(),
abilities: [BossAbilityType.stunAttack],
@@ -301,6 +318,11 @@ class BossStats extends MonsterBaseStats {
}
/// Glitch God (최종 보스, 레벨 100)
///
/// Phase 6 밸런스 조정:
/// - enrageThreshold: 0.1 → 0.15 (분노 발동 시점 완화)
/// - enrageMultiplier: 2.0 → 1.7 (분노 시 스탯 증가 완화)
/// - shieldAmount: 50% → 35% (보호막 감소)
static BossStats glitchGod(int baseLevel) {
final base = MonsterBaseStats.generate(baseLevel, MonsterType.finalBoss);
return BossStats(
@@ -310,10 +332,10 @@ class BossStats extends MonsterBaseStats {
exp: base.exp,
gold: base.gold,
phases: 5,
enrageThreshold: 0.1,
enrageMultiplier: 2.0,
enrageThreshold: 0.15, // 0.1 → 0.15 (15% HP에서 분노)
enrageMultiplier: 1.7, // 2.0 → 1.7 (분노 시 70% 스탯 증가)
hasShield: true,
shieldAmount: (base.hp * 0.5).round(),
shieldAmount: (base.hp * 0.35).round(), // 0.5 → 0.35 (보호막 30% 감소)
abilities: [
BossAbilityType.phaseShift,
BossAbilityType.multiAttack,
@@ -398,11 +420,17 @@ class LevelTierSettings {
class PlayerScaling {
PlayerScaling._();
/// 레벨당 HP 증가량
static const int hpPerLevel = 10;
/// 레벨당 HP 증가량 (10 → 12 상향)
static const int hpPerLevel = 12;
/// 레벨당 MP 증가량
static const int mpPerLevel = 5;
/// 레벨당 MP 증가량 (5 → 6 상향)
static const int mpPerLevel = 6;
/// CON당 HP 보너스 (5 → 6 상향)
static const int hpPerCon = 6;
/// INT당 MP 보너스 (3 → 4 상향)
static const int mpPerInt = 4;
/// 레벨업 시 HP/MP 계산
static ({int hpMax, int mpMax}) calculateResources({
@@ -412,8 +440,17 @@ class PlayerScaling {
required int conBonus,
required int intBonus,
}) {
final hpMax = baseHp + (level - 1) * hpPerLevel + conBonus * 5;
final mpMax = baseMp + (level - 1) * mpPerLevel + intBonus * 3;
final hpMax = baseHp + (level - 1) * hpPerLevel + conBonus * hpPerCon;
final mpMax = baseMp + (level - 1) * mpPerLevel + intBonus * mpPerInt;
return (hpMax: hpMax, mpMax: mpMax);
}
/// 레벨 구간별 ATK 보너스 (후반 DPS 보조)
/// - 레벨 60+: +1 ATK per level
/// - 레벨 80+: +2 ATK per level
static int bonusAtk(int level) {
if (level >= 80) return (level - 80) * 2 + 20;
if (level >= 60) return level - 60;
return 0;
}
}