- ItemStats, CombatStats, EquipmentItem을 freezed로 마이그레이션 - copyWith, toJson/fromJson 자동 생성 - 세이브 파일 호환성 유지
97 lines
2.6 KiB
Dart
97 lines
2.6 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
import 'package:asciineverdie/src/core/model/equipment_slot.dart';
|
|
import 'package:asciineverdie/src/core/model/item_stats.dart';
|
|
|
|
part 'equipment_item.freezed.dart';
|
|
part 'equipment_item.g.dart';
|
|
|
|
/// 장비 아이템
|
|
///
|
|
/// 개별 장비의 이름, 슬롯, 레벨, 스탯 등을 포함하는 클래스.
|
|
/// 불변(immutable) 객체로 설계됨.
|
|
@freezed
|
|
class EquipmentItem with _$EquipmentItem {
|
|
const EquipmentItem._();
|
|
|
|
const factory EquipmentItem({
|
|
/// 아이템 이름 (예: "Flaming Sword of Doom")
|
|
required String name,
|
|
/// 장착 슬롯
|
|
@JsonKey(fromJson: _slotFromJson, toJson: _slotToJson)
|
|
required EquipmentSlot slot,
|
|
/// 아이템 레벨
|
|
required int level,
|
|
/// 무게 (STR 기반 휴대 제한용)
|
|
required int weight,
|
|
/// 아이템 스탯 보정치
|
|
required ItemStats stats,
|
|
/// 희귀도
|
|
@JsonKey(fromJson: _rarityFromJson, toJson: _rarityToJson)
|
|
required ItemRarity rarity,
|
|
}) = _EquipmentItem;
|
|
|
|
factory EquipmentItem.fromJson(Map<String, dynamic> json) =>
|
|
_$EquipmentItemFromJson(json);
|
|
|
|
/// 빈 아이템 생성 (특정 슬롯)
|
|
factory EquipmentItem.empty(EquipmentSlot slot) {
|
|
return EquipmentItem(
|
|
name: '',
|
|
slot: slot,
|
|
level: 0,
|
|
weight: 0,
|
|
stats: const ItemStats(),
|
|
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,
|
|
);
|
|
}
|
|
|
|
/// 가중치 (자동 장착 비교용)
|
|
///
|
|
/// 가중치 = 기본값 + (레벨 * 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;
|
|
|
|
@override
|
|
String toString() => name.isEmpty ? '(empty)' : name;
|
|
}
|
|
|
|
// JSON 변환 헬퍼 (세이브 파일 호환성 유지)
|
|
EquipmentSlot _slotFromJson(String? value) {
|
|
return EquipmentSlot.values.firstWhere(
|
|
(s) => s.name == value,
|
|
orElse: () => EquipmentSlot.weapon,
|
|
);
|
|
}
|
|
|
|
String _slotToJson(EquipmentSlot slot) => slot.name;
|
|
|
|
ItemRarity _rarityFromJson(String? value) {
|
|
return ItemRarity.values.firstWhere(
|
|
(r) => r.name == value,
|
|
orElse: () => ItemRarity.common,
|
|
);
|
|
}
|
|
|
|
String _rarityToJson(ItemRarity rarity) => rarity.name;
|