import 'package:asciineverdie/src/core/model/equipment_slot.dart'; import 'package:asciineverdie/src/core/model/item_stats.dart'; /// 장비 아이템 /// /// 개별 장비의 이름, 슬롯, 레벨, 스탯 등을 포함하는 클래스. /// 불변(immutable) 객체로 설계됨. class EquipmentItem { const EquipmentItem({ required this.name, required this.slot, required this.level, required this.weight, required this.stats, required this.rarity, }); /// 아이템 이름 (예: "Flaming Sword of Doom") final String name; /// 장착 슬롯 final EquipmentSlot slot; /// 아이템 레벨 final int level; /// 무게 (STR 기반 휴대 제한용) final int weight; /// 아이템 스탯 보정치 final ItemStats stats; /// 희귀도 final ItemRarity rarity; /// 가중치 (자동 장착 비교용) /// /// 가중치 = 기본값 + (레벨 * 10) + (희귀도 보너스) + (스탯 합계) int get itemWeight { const baseValue = 10; return baseValue + (level * 10) + rarity.weightBonus + stats.totalStatValue; } /// 빈 아이템 여부 bool get isEmpty => name.isEmpty; /// 유효한 아이템 여부 bool get isNotEmpty => name.isNotEmpty; /// 빈 아이템 생성 (특정 슬롯) factory EquipmentItem.empty(EquipmentSlot slot) { return EquipmentItem( name: '', slot: slot, level: 0, weight: 0, stats: ItemStats.empty, rarity: ItemRarity.common, ); } /// 기본 무기 (Keyboard) factory EquipmentItem.defaultWeapon() { return const EquipmentItem( name: 'Keyboard', slot: EquipmentSlot.weapon, level: 1, weight: 5, stats: ItemStats(atk: 1, attackSpeed: 1000), rarity: ItemRarity.common, ); } EquipmentItem copyWith({ String? name, EquipmentSlot? slot, int? level, int? weight, ItemStats? stats, ItemRarity? rarity, }) { return EquipmentItem( name: name ?? this.name, slot: slot ?? this.slot, level: level ?? this.level, weight: weight ?? this.weight, stats: stats ?? this.stats, rarity: rarity ?? this.rarity, ); } /// JSON으로 직렬화 Map toJson() { return { 'name': name, 'slot': slot.name, 'level': level, 'weight': weight, 'stats': stats.toJson(), 'rarity': rarity.name, }; } /// JSON에서 역직렬화 factory EquipmentItem.fromJson(Map json) { final slotName = json['slot'] as String? ?? 'weapon'; final rarityName = json['rarity'] as String? ?? 'common'; return EquipmentItem( name: json['name'] as String? ?? '', slot: EquipmentSlot.values.firstWhere( (s) => s.name == slotName, orElse: () => EquipmentSlot.weapon, ), level: json['level'] as int? ?? 0, weight: json['weight'] as int? ?? 0, stats: json['stats'] != null ? ItemStats.fromJson(json['stats'] as Map) : ItemStats.empty, rarity: ItemRarity.values.firstWhere( (r) => r.name == rarityName, orElse: () => ItemRarity.common, ), ); } @override String toString() => name.isEmpty ? '(empty)' : name; }