/// 물약 종류 enum PotionType { /// HP 회복 물약 hp, /// MP 회복 물약 mp, } /// 물약 아이템 /// /// 전투 중 사용 가능한 소모품. /// 전투당 종류별 1회만 사용 가능. class Potion { const Potion({ required this.id, required this.name, required this.type, required this.tier, this.healAmount = 0, this.healPercent = 0.0, this.price = 0, }); /// 물약 ID final String id; /// 물약 이름 final String name; /// 물약 종류 (hp / mp) final PotionType type; /// 물약 티어 (1~5, 높을수록 강력) final int tier; /// 고정 회복량 final int healAmount; /// 비율 회복량 (0.0 ~ 1.0) final double healPercent; /// 구매 가격 (골드) final int price; /// HP 물약 여부 bool get isHpPotion => type == PotionType.hp; /// MP 물약 여부 bool get isMpPotion => type == PotionType.mp; /// 실제 회복량 계산 /// /// [maxValue] 최대 HP 또는 MP int calculateHeal(int maxValue) { final percentHeal = (maxValue * healPercent).round(); return healAmount + percentHeal; } } /// 물약 인벤토리 상태 /// /// 보유 물약 수량 및 전투 중 사용 기록 관리 class PotionInventory { const PotionInventory({ this.potions = const {}, this.usedInBattle = const {}, }); /// 보유 물약 (물약 ID → 수량) final Map potions; /// 현재 전투에서 사용한 물약 종류 final Set usedInBattle; /// 물약 보유 여부 bool hasPotion(String potionId) => (potions[potionId] ?? 0) > 0; /// 물약 수량 조회 int getQuantity(String potionId) => potions[potionId] ?? 0; /// 특정 종류 물약 사용 가능 여부 /// /// 전투당 종류별 1회 제한 체크 bool canUseType(PotionType type) => !usedInBattle.contains(type); /// 물약 추가 PotionInventory addPotion(String potionId, [int count = 1]) { final newPotions = Map.from(potions); newPotions[potionId] = (newPotions[potionId] ?? 0) + count; return PotionInventory(potions: newPotions, usedInBattle: usedInBattle); } /// 물약 사용 (수량 감소) PotionInventory usePotion(String potionId, PotionType type) { final currentQty = potions[potionId] ?? 0; if (currentQty <= 0) return this; final newPotions = Map.from(potions); newPotions[potionId] = currentQty - 1; if (newPotions[potionId] == 0) { newPotions.remove(potionId); } final newUsed = Set.from(usedInBattle)..add(type); return PotionInventory(potions: newPotions, usedInBattle: newUsed); } /// 전투 종료 시 사용 기록 초기화 PotionInventory resetBattleUsage() { return PotionInventory(potions: potions, usedInBattle: const {}); } /// 빈 인벤토리 static const empty = PotionInventory(); PotionInventory copyWith({ Map? potions, Set? usedInBattle, }) { return PotionInventory( potions: potions ?? this.potions, usedInBattle: usedInBattle ?? this.usedInBattle, ); } }