- CombatEventType.playerDebuff 추가 - CombatState에 activeDebuffs 목록 추가 - SkillService.useDebuffSkill() 구현 - 스킬 자동 선택에 디버프 우선순위 추가 - 밸런스 상수 업데이트
276 lines
6.2 KiB
Dart
276 lines
6.2 KiB
Dart
/// 전투 이벤트 타입 (Combat Event Type)
|
|
enum CombatEventType {
|
|
/// 플레이어가 몬스터 공격
|
|
playerAttack,
|
|
|
|
/// 몬스터가 플레이어 공격
|
|
monsterAttack,
|
|
|
|
/// 플레이어 회피
|
|
playerEvade,
|
|
|
|
/// 몬스터 회피
|
|
monsterEvade,
|
|
|
|
/// 플레이어 방패 방어
|
|
playerBlock,
|
|
|
|
/// 플레이어 무기 쳐내기
|
|
playerParry,
|
|
|
|
/// 플레이어 스킬 사용
|
|
playerSkill,
|
|
|
|
/// 플레이어 회복
|
|
playerHeal,
|
|
|
|
/// 플레이어 버프
|
|
playerBuff,
|
|
|
|
/// 플레이어 디버프 (적에게 적용)
|
|
playerDebuff,
|
|
|
|
/// DOT 틱 데미지
|
|
dotTick,
|
|
|
|
/// 물약 사용
|
|
playerPotion,
|
|
|
|
/// 물약 드랍
|
|
potionDrop,
|
|
}
|
|
|
|
/// 전투 이벤트 (Combat Event)
|
|
///
|
|
/// 개별 공격/방어/스킬 사용 등의 전투 행동을 기록
|
|
class CombatEvent {
|
|
const CombatEvent({
|
|
required this.type,
|
|
required this.timestamp,
|
|
this.damage = 0,
|
|
this.healAmount = 0,
|
|
this.isCritical = false,
|
|
this.skillName,
|
|
this.targetName,
|
|
this.attackDelayMs,
|
|
});
|
|
|
|
/// 이벤트 타입
|
|
final CombatEventType type;
|
|
|
|
/// 발생 시간 (elapsedMs)
|
|
final int timestamp;
|
|
|
|
/// 데미지 (0이면 미스/회피)
|
|
final int damage;
|
|
|
|
/// 회복량 (회복 이벤트용)
|
|
final int healAmount;
|
|
|
|
/// 크리티컬 여부
|
|
final bool isCritical;
|
|
|
|
/// 사용한 스킬 이름 (스킬 이벤트용)
|
|
final String? skillName;
|
|
|
|
/// 대상 이름 (몬스터 또는 플레이어)
|
|
final String? targetName;
|
|
|
|
/// 공격자의 공격 속도 (ms)
|
|
/// 애니메이션 페이즈 지속 시간 계산에 사용
|
|
final int? attackDelayMs;
|
|
|
|
/// 플레이어 공격 이벤트 생성
|
|
factory CombatEvent.playerAttack({
|
|
required int timestamp,
|
|
required int damage,
|
|
required String targetName,
|
|
bool isCritical = false,
|
|
int? attackDelayMs,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerAttack,
|
|
timestamp: timestamp,
|
|
damage: damage,
|
|
targetName: targetName,
|
|
isCritical: isCritical,
|
|
attackDelayMs: attackDelayMs,
|
|
);
|
|
}
|
|
|
|
/// 몬스터 공격 이벤트 생성
|
|
factory CombatEvent.monsterAttack({
|
|
required int timestamp,
|
|
required int damage,
|
|
required String attackerName,
|
|
int? attackDelayMs,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.monsterAttack,
|
|
timestamp: timestamp,
|
|
damage: damage,
|
|
targetName: attackerName,
|
|
attackDelayMs: attackDelayMs,
|
|
);
|
|
}
|
|
|
|
/// 플레이어 회피 이벤트 생성
|
|
factory CombatEvent.playerEvade({
|
|
required int timestamp,
|
|
required String attackerName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerEvade,
|
|
timestamp: timestamp,
|
|
targetName: attackerName,
|
|
);
|
|
}
|
|
|
|
/// 몬스터 회피 이벤트 생성
|
|
factory CombatEvent.monsterEvade({
|
|
required int timestamp,
|
|
required String targetName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.monsterEvade,
|
|
timestamp: timestamp,
|
|
targetName: targetName,
|
|
);
|
|
}
|
|
|
|
/// 플레이어 방패 방어 이벤트 생성
|
|
factory CombatEvent.playerBlock({
|
|
required int timestamp,
|
|
required int reducedDamage,
|
|
required String attackerName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerBlock,
|
|
timestamp: timestamp,
|
|
damage: reducedDamage,
|
|
targetName: attackerName,
|
|
);
|
|
}
|
|
|
|
/// 플레이어 무기 쳐내기 이벤트 생성
|
|
factory CombatEvent.playerParry({
|
|
required int timestamp,
|
|
required int reducedDamage,
|
|
required String attackerName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerParry,
|
|
timestamp: timestamp,
|
|
damage: reducedDamage,
|
|
targetName: attackerName,
|
|
);
|
|
}
|
|
|
|
/// 스킬 사용 이벤트 생성
|
|
factory CombatEvent.playerSkill({
|
|
required int timestamp,
|
|
required String skillName,
|
|
required int damage,
|
|
required String targetName,
|
|
bool isCritical = false,
|
|
int? attackDelayMs,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerSkill,
|
|
timestamp: timestamp,
|
|
skillName: skillName,
|
|
damage: damage,
|
|
targetName: targetName,
|
|
isCritical: isCritical,
|
|
attackDelayMs: attackDelayMs,
|
|
);
|
|
}
|
|
|
|
/// 회복 이벤트 생성
|
|
factory CombatEvent.playerHeal({
|
|
required int timestamp,
|
|
required int healAmount,
|
|
String? skillName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerHeal,
|
|
timestamp: timestamp,
|
|
healAmount: healAmount,
|
|
skillName: skillName,
|
|
);
|
|
}
|
|
|
|
/// 버프 이벤트 생성
|
|
factory CombatEvent.playerBuff({
|
|
required int timestamp,
|
|
required String skillName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerBuff,
|
|
timestamp: timestamp,
|
|
skillName: skillName,
|
|
);
|
|
}
|
|
|
|
/// 디버프 이벤트 생성 (적에게 디버프 적용)
|
|
factory CombatEvent.playerDebuff({
|
|
required int timestamp,
|
|
required String skillName,
|
|
required String targetName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerDebuff,
|
|
timestamp: timestamp,
|
|
skillName: skillName,
|
|
targetName: targetName,
|
|
);
|
|
}
|
|
|
|
/// DOT 틱 이벤트 생성
|
|
factory CombatEvent.dotTick({
|
|
required int timestamp,
|
|
required String skillName,
|
|
required int damage,
|
|
required String targetName,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.dotTick,
|
|
timestamp: timestamp,
|
|
skillName: skillName,
|
|
damage: damage,
|
|
targetName: targetName,
|
|
);
|
|
}
|
|
|
|
/// 물약 사용 이벤트 생성
|
|
factory CombatEvent.playerPotion({
|
|
required int timestamp,
|
|
required String potionName,
|
|
required int healAmount,
|
|
required bool isHp,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.playerPotion,
|
|
timestamp: timestamp,
|
|
skillName: potionName,
|
|
healAmount: healAmount,
|
|
// isHp를 구분하기 위해 targetName 사용 (HP/MP)
|
|
targetName: isHp ? 'HP' : 'MP',
|
|
);
|
|
}
|
|
|
|
/// 물약 드랍 이벤트 생성
|
|
factory CombatEvent.potionDrop({
|
|
required int timestamp,
|
|
required String potionName,
|
|
required bool isHp,
|
|
}) {
|
|
return CombatEvent(
|
|
type: CombatEventType.potionDrop,
|
|
timestamp: timestamp,
|
|
skillName: potionName,
|
|
targetName: isHp ? 'HP' : 'MP',
|
|
);
|
|
}
|
|
}
|