feat(item): Phase 2 아이템 시스템 구현

- ItemStats, ItemRarity 클래스 추가 (아이템 스탯/희귀도)
- EquipmentItem 클래스 추가 (개별 장비 아이템)
- ItemService 추가 (아이템 생성/관리/무게 시스템)
- Equipment 클래스 확장 (EquipmentItem 기반, 기존 API 호환)
- CombatStats에서 장비 스탯 반영
- 레거시 세이브 파일 호환성 유지
This commit is contained in:
JiWoong Sul
2025-12-17 16:57:23 +09:00
parent c62687f7bd
commit 6a696ecd57
6 changed files with 726 additions and 122 deletions

View File

@@ -0,0 +1,182 @@
/// 아이템 희귀도
enum ItemRarity {
common,
uncommon,
rare,
epic,
legendary;
/// 희귀도 배율 (스탯 계산용)
double get multiplier => switch (this) {
common => 1.0,
uncommon => 1.3,
rare => 1.7,
epic => 2.2,
legendary => 3.0,
};
/// 가중치 보너스
int get weightBonus => switch (this) {
common => 0,
uncommon => 50,
rare => 150,
epic => 400,
legendary => 1000,
};
}
/// 아이템 스탯 보정치
///
/// 장비 아이템이 제공하는 스탯 보너스.
/// 모든 값은 기본 0이며, 장착 시 플레이어 스탯에 가산됨.
class ItemStats {
const ItemStats({
this.atk = 0,
this.def = 0,
this.magAtk = 0,
this.magDef = 0,
this.criRate = 0.0,
this.evasion = 0.0,
this.blockRate = 0.0,
this.parryRate = 0.0,
this.hpBonus = 0,
this.mpBonus = 0,
this.strBonus = 0,
this.conBonus = 0,
this.dexBonus = 0,
this.intBonus = 0,
this.wisBonus = 0,
this.chaBonus = 0,
});
/// 물리 공격력 보정
final int atk;
/// 물리 방어력 보정
final int def;
/// 마법 공격력 보정
final int magAtk;
/// 마법 방어력 보정
final int magDef;
/// 크리티컬 확률 보정 (0.0 ~ 1.0)
final double criRate;
/// 회피율 보정 (0.0 ~ 1.0)
final double evasion;
/// 방패 방어율 (방패 전용, 0.0 ~ 1.0)
final double blockRate;
/// 무기 쳐내기 확률 (무기 전용, 0.0 ~ 1.0)
final double parryRate;
/// HP 보너스
final int hpBonus;
/// MP 보너스
final int mpBonus;
/// STR 보너스
final int strBonus;
/// CON 보너스
final int conBonus;
/// DEX 보너스
final int dexBonus;
/// INT 보너스
final int intBonus;
/// WIS 보너스
final int wisBonus;
/// CHA 보너스
final int chaBonus;
/// 스탯 합계 (가중치 계산용)
int get totalStatValue {
return atk +
def +
magAtk +
magDef +
(criRate * 100).round() +
(evasion * 100).round() +
(blockRate * 100).round() +
(parryRate * 100).round() +
hpBonus +
mpBonus +
strBonus * 5 +
conBonus * 5 +
dexBonus * 5 +
intBonus * 5 +
wisBonus * 5 +
chaBonus * 5;
}
/// 빈 스탯 (보너스 없음)
static const empty = ItemStats();
/// 두 스탯 합산
ItemStats operator +(ItemStats other) {
return ItemStats(
atk: atk + other.atk,
def: def + other.def,
magAtk: magAtk + other.magAtk,
magDef: magDef + other.magDef,
criRate: criRate + other.criRate,
evasion: evasion + other.evasion,
blockRate: blockRate + other.blockRate,
parryRate: parryRate + other.parryRate,
hpBonus: hpBonus + other.hpBonus,
mpBonus: mpBonus + other.mpBonus,
strBonus: strBonus + other.strBonus,
conBonus: conBonus + other.conBonus,
dexBonus: dexBonus + other.dexBonus,
intBonus: intBonus + other.intBonus,
wisBonus: wisBonus + other.wisBonus,
chaBonus: chaBonus + other.chaBonus,
);
}
ItemStats copyWith({
int? atk,
int? def,
int? magAtk,
int? magDef,
double? criRate,
double? evasion,
double? blockRate,
double? parryRate,
int? hpBonus,
int? mpBonus,
int? strBonus,
int? conBonus,
int? dexBonus,
int? intBonus,
int? wisBonus,
int? chaBonus,
}) {
return ItemStats(
atk: atk ?? this.atk,
def: def ?? this.def,
magAtk: magAtk ?? this.magAtk,
magDef: magDef ?? this.magDef,
criRate: criRate ?? this.criRate,
evasion: evasion ?? this.evasion,
blockRate: blockRate ?? this.blockRate,
parryRate: parryRate ?? this.parryRate,
hpBonus: hpBonus ?? this.hpBonus,
mpBonus: mpBonus ?? this.mpBonus,
strBonus: strBonus ?? this.strBonus,
conBonus: conBonus ?? this.conBonus,
dexBonus: dexBonus ?? this.dexBonus,
intBonus: intBonus ?? this.intBonus,
wisBonus: wisBonus ?? this.wisBonus,
chaBonus: chaBonus ?? this.chaBonus,
);
}
}