feat(engine): GCD 체크 및 스킬 자동 장착 로직 구현
SkillService: - canUseSkill()에 GCD 체크 추가 - selectAutoSkill() 확률 조정 (70% 일반공격, 30% 스킬) - 버프/디버프 조건 강화 (HP>80%, 활성 효과 체크) ProgressService: - 스킬 사용 후 GCD 시작 로직 추가 - 장착된 스킬 슬롯에서 사용 가능 스킬 조회 - 비전투 태스크 시 currentCombat 초기화 GameMutations: - winSpell()에서 스펠 획득 시 전투 스킬 자동 장착
This commit is contained in:
@@ -24,6 +24,11 @@ class SkillService {
|
||||
required int currentMp,
|
||||
required SkillSystemState skillSystem,
|
||||
}) {
|
||||
// GCD 체크 (글로벌 쿨타임 1500ms)
|
||||
if (skillSystem.isGlobalCooldownActive) {
|
||||
return SkillFailReason.onGlobalCooldown;
|
||||
}
|
||||
|
||||
// MP 체크
|
||||
if (currentMp < skill.mpCost) {
|
||||
return SkillFailReason.notEnoughMp;
|
||||
@@ -297,13 +302,14 @@ class SkillService {
|
||||
/// 전투 중 자동 스킬 선택
|
||||
///
|
||||
/// 우선순위:
|
||||
/// 1. HP < 30% → 회복 스킬
|
||||
/// 2. HP > 70% & MP > 50% → 버프 스킬 (안전할 때)
|
||||
/// 3. 몬스터 HP > 70% & 활성 디버프 없음 → 디버프 스킬
|
||||
/// 4. 몬스터 HP > 50% & DOT 없음 → DOT 스킬 (장기전 유리)
|
||||
/// 5. 보스전 (레벨 차이 10 이상) → 가장 강력한 공격 스킬
|
||||
/// 6. 일반 전투 → MP 효율이 좋은 스킬
|
||||
/// 7. MP < 20% → null (일반 공격)
|
||||
/// 1. HP < 30% → 회복 스킬 (최우선)
|
||||
/// 2. 70% 확률로 일반 공격 (MP 절약, 기본 전투)
|
||||
/// 3. 30% 확률로 스킬 사용:
|
||||
/// - 버프: HP > 80% & MP > 60% & 활성 버프 없음
|
||||
/// - 디버프: 몬스터 HP > 80% & 활성 디버프 없음
|
||||
/// - DOT: 몬스터 HP > 60% & 활성 DOT 없음
|
||||
/// - 공격: 보스전이면 강력한 스킬, 일반전이면 효율적 스킬
|
||||
/// 4. MP < 20% → 일반 공격
|
||||
Skill? selectAutoSkill({
|
||||
required CombatStats player,
|
||||
required MonsterCombatStats monster,
|
||||
@@ -336,39 +342,49 @@ class SkillService {
|
||||
|
||||
if (availableSkills.isEmpty) return null;
|
||||
|
||||
// HP < 30% → 회복 스킬 우선
|
||||
// HP < 30% → 회복 스킬 최우선 (생존)
|
||||
if (hpRatio < 0.3) {
|
||||
final healSkill = _findBestHealSkill(availableSkills, currentMp);
|
||||
if (healSkill != null) return healSkill;
|
||||
}
|
||||
|
||||
// HP > 70% & MP > 50% → 버프 스킬 (안전할 때)
|
||||
if (hpRatio > 0.7 && mpRatio > 0.5) {
|
||||
final buffSkill = _findBestBuffSkill(availableSkills, currentMp);
|
||||
if (buffSkill != null) return buffSkill;
|
||||
// 70% 확률로 일반 공격 (스킬은 특별한 상황에서만)
|
||||
final useNormalAttack = rng.nextInt(100) < 70;
|
||||
if (useNormalAttack) return null;
|
||||
|
||||
// === 아래부터 30% 확률로 스킬 사용 ===
|
||||
|
||||
// 버프: HP > 80% & MP > 60% (매우 안전할 때만)
|
||||
// 활성 버프가 있으면 건너뜀 (중복 방지)
|
||||
if (hpRatio > 0.8 && mpRatio > 0.6) {
|
||||
final hasActiveBuff = skillSystem.activeBuffs.isNotEmpty;
|
||||
if (!hasActiveBuff) {
|
||||
final buffSkill = _findBestBuffSkill(availableSkills, currentMp);
|
||||
if (buffSkill != null) return buffSkill;
|
||||
}
|
||||
}
|
||||
|
||||
// 몬스터 HP > 70% & 활성 디버프 없음 → 디버프 스킬
|
||||
if (monster.hpRatio > 0.7 && activeDebuffs.isEmpty) {
|
||||
// 디버프: 몬스터 HP > 80% & 활성 디버프 없음 (전투 초반)
|
||||
if (monster.hpRatio > 0.8 && activeDebuffs.isEmpty) {
|
||||
final debuffSkill = _findBestDebuffSkill(availableSkills, currentMp);
|
||||
if (debuffSkill != null) return debuffSkill;
|
||||
}
|
||||
|
||||
// 몬스터 HP > 50% & 활성 DOT 없음 → DOT 스킬 사용
|
||||
if (monster.hpRatio > 0.5 && activeDoTs.isEmpty) {
|
||||
// DOT: 몬스터 HP > 60% & 활성 DOT 없음 (장기전 유리)
|
||||
if (monster.hpRatio > 0.6 && activeDoTs.isEmpty) {
|
||||
final dotSkill = _findBestDotSkill(availableSkills, currentMp);
|
||||
if (dotSkill != null) return dotSkill;
|
||||
}
|
||||
|
||||
// 보스전 판단 (몬스터 레벨이 높음)
|
||||
final isBossFight = monster.level >= 10 && monster.hpRatio > 0.5;
|
||||
// 보스전 판단 (몬스터 레벨 20 이상 & HP 50% 이상)
|
||||
final isBossFight = monster.level >= 20 && monster.hpRatio > 0.5;
|
||||
|
||||
if (isBossFight) {
|
||||
// 가장 강력한 공격 스킬
|
||||
return _findStrongestAttackSkill(availableSkills);
|
||||
}
|
||||
|
||||
// 일반 전투 → MP 효율 좋은 스킬
|
||||
// 일반 전투 → MP 효율 좋은 공격 스킬
|
||||
return _findEfficientAttackSkill(availableSkills);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user