/// 전투 이벤트 타입 (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', ); } }