/// 스킬 타입 enum SkillType { /// 공격 스킬 attack, /// 회복 스킬 heal, /// 버프 스킬 buff, /// 디버프 스킬 debuff, } /// 버프 효과 class BuffEffect { const BuffEffect({ required this.id, required this.name, required this.durationMs, this.atkModifier = 0.0, this.defModifier = 0.0, this.criRateModifier = 0.0, this.evasionModifier = 0.0, }); /// 버프 ID final String id; /// 버프 이름 final String name; /// 지속 시간 (밀리초) final int durationMs; /// 공격력 배율 보정 (0.0 = 변화 없음, 0.5 = +50%) final double atkModifier; /// 방어력 배율 보정 final double defModifier; /// 크리티컬 확률 보정 final double criRateModifier; /// 회피율 보정 final double evasionModifier; } /// 스킬 정의 class Skill { const Skill({ required this.id, required this.name, required this.type, required this.mpCost, required this.cooldownMs, required this.power, this.damageMultiplier = 1.0, this.healAmount = 0, this.healPercent = 0.0, this.buff, this.selfDamagePercent = 0.0, this.targetDefReduction = 0.0, }); /// 스킬 ID final String id; /// 스킬 이름 final String name; /// 스킬 타입 final SkillType type; /// MP 소모량 final int mpCost; /// 쿨타임 (밀리초) final int cooldownMs; /// 스킬 위력 (기본 값) final int power; /// 데미지 배율 (공격 스킬용) final double damageMultiplier; /// 고정 회복량 (회복 스킬용) final int healAmount; /// HP% 회복 (회복 스킬용, 0.0 ~ 1.0) final double healPercent; /// 버프 효과 (버프/디버프 스킬용) final BuffEffect? buff; /// 자해 데미지 % (일부 강력한 스킬) final double selfDamagePercent; /// 적 방어력 감소 % (일부 공격 스킬) final double targetDefReduction; /// 공격 스킬 여부 bool get isAttack => type == SkillType.attack; /// 회복 스킬 여부 bool get isHeal => type == SkillType.heal; /// 버프 스킬 여부 bool get isBuff => type == SkillType.buff; /// 디버프 스킬 여부 bool get isDebuff => type == SkillType.debuff; /// MP 효율 (데미지 당 MP 비용) double get mpEfficiency { if (type != SkillType.attack || damageMultiplier <= 0) return 0; return damageMultiplier / mpCost; } } /// 스킬 사용 상태 (쿨타임 추적) class SkillState { const SkillState({ required this.skillId, required this.lastUsedMs, required this.rank, }); /// 스킬 ID final String skillId; /// 마지막 사용 시간 (게임 내 경과 시간, 밀리초) final int lastUsedMs; /// 스킬 랭크 (레벨) final int rank; /// 쿨타임 완료 여부 bool isReady(int currentMs, int cooldownMs) { return currentMs - lastUsedMs >= cooldownMs; } /// 남은 쿨타임 (밀리초) int remainingCooldown(int currentMs, int cooldownMs) { final elapsed = currentMs - lastUsedMs; if (elapsed >= cooldownMs) return 0; return cooldownMs - elapsed; } SkillState copyWith({ String? skillId, int? lastUsedMs, int? rank, }) { return SkillState( skillId: skillId ?? this.skillId, lastUsedMs: lastUsedMs ?? this.lastUsedMs, rank: rank ?? this.rank, ); } /// 새 스킬 상태 생성 (쿨타임 0) factory SkillState.fresh(String skillId, {int rank = 1}) { return SkillState( skillId: skillId, lastUsedMs: -999999, // 즉시 사용 가능하도록 먼 과거 rank: rank, ); } } /// 활성 버프 상태 class ActiveBuff { const ActiveBuff({ required this.effect, required this.startedMs, required this.sourceSkillId, }); /// 버프 효과 final BuffEffect effect; /// 버프 시작 시간 (게임 내 경과 시간) final int startedMs; /// 버프를 발동한 스킬 ID final String sourceSkillId; /// 버프 만료 여부 bool isExpired(int currentMs) { return currentMs - startedMs >= effect.durationMs; } /// 남은 지속 시간 (밀리초) int remainingDuration(int currentMs) { final elapsed = currentMs - startedMs; if (elapsed >= effect.durationMs) return 0; return effect.durationMs - elapsed; } ActiveBuff copyWith({ BuffEffect? effect, int? startedMs, String? sourceSkillId, }) { return ActiveBuff( effect: effect ?? this.effect, startedMs: startedMs ?? this.startedMs, sourceSkillId: sourceSkillId ?? this.sourceSkillId, ); } } /// 스킬 사용 결과 class SkillUseResult { const SkillUseResult({ required this.skill, required this.success, this.damage = 0, this.healedAmount = 0, this.appliedBuff, this.failReason, }); /// 사용한 스킬 final Skill skill; /// 성공 여부 final bool success; /// 데미지 (공격 스킬) final int damage; /// 회복량 (회복 스킬) final int healedAmount; /// 적용된 버프 (버프 스킬) final ActiveBuff? appliedBuff; /// 실패 사유 final SkillFailReason? failReason; /// 실패 결과 생성 factory SkillUseResult.failed(Skill skill, SkillFailReason reason) { return SkillUseResult( skill: skill, success: false, failReason: reason, ); } } /// 스킬 실패 사유 enum SkillFailReason { /// MP 부족 notEnoughMp, /// 쿨타임 중 onCooldown, /// 스킬 없음 skillNotFound, /// 사용 불가 상태 invalidState, }