- 121KB 단일 문서를 22개 태스크 문서로 분리 - 메인 인덱스 문서 (game-system-overhaul-index.md) 생성 - Phase 1-10 태스크 문서 10개 분리 - 추가 시스템 태스크 문서 10개 분리 - 재미 요소 설계 문서 1개 분리 - 기존 문서는 archive/ 폴더로 이동
137 lines
3.7 KiB
Markdown
137 lines
3.7 KiB
Markdown
# Phase 2: 아이템 시스템
|
|
|
|
> 메인 문서: [game-system-overhaul-index.md](game-system-overhaul-index.md)
|
|
|
|
---
|
|
|
|
## 목표
|
|
아이템에 스탯 보정치를 부여하고, 가중치 시스템을 도입한다.
|
|
|
|
## 아이템 스탯 구조
|
|
|
|
```dart
|
|
class ItemStats {
|
|
final int atk; // 공격력 보정
|
|
final int def; // 방어력 보정
|
|
final int magAtk; // 마법 공격력 보정
|
|
final int magDef; // 마법 방어력 보정
|
|
final double criRate; // 크리티컬 확률 보정
|
|
final double evasion; // 회피율 보정
|
|
final double blockRate; // 방패 방어율 (방패 전용)
|
|
final double parryRate; // 무기 쳐내기 (무기 전용)
|
|
|
|
// 추가 효과
|
|
final int hpBonus;
|
|
final int mpBonus;
|
|
final int strBonus;
|
|
final int dexBonus;
|
|
// ... 기타 스탯 보너스
|
|
}
|
|
|
|
class Equipment {
|
|
final String name;
|
|
final EquipmentSlot slot;
|
|
final int level; // 아이템 레벨
|
|
final int weight; // 가중치 (높을수록 좋은 아이템)
|
|
final ItemStats stats;
|
|
final ItemRarity rarity; // Common, Uncommon, Rare, Epic, Legendary
|
|
}
|
|
```
|
|
|
|
## 아이템 가중치 계산
|
|
|
|
```
|
|
가중치 = 기본값 + (레벨 * 10) + (희귀도 보너스) + (스탯 합계)
|
|
|
|
희귀도 보너스:
|
|
- Common: 0
|
|
- Uncommon: 50
|
|
- Rare: 150
|
|
- Epic: 400
|
|
- Legendary: 1000
|
|
```
|
|
|
|
## 자동 장착 로직
|
|
|
|
```
|
|
1. 인벤토리에서 장착 가능한 아이템 필터링
|
|
2. 슬롯별로 그룹화
|
|
3. 각 슬롯에서 가장 높은 가중치 아이템 선택
|
|
4. 무게 제한 체크 (총 무게 ≤ STR 기반 최대 무게)
|
|
5. 현재 장비와 비교하여 더 좋으면 교체
|
|
```
|
|
|
|
### 무게 제한 시스템
|
|
|
|
```dart
|
|
class WeightSystem {
|
|
/// STR 기반 최대 휴대 가능 무게
|
|
int calculateMaxWeight(int str) {
|
|
// 기본 100 + STR당 10
|
|
return 100 + str * 10;
|
|
}
|
|
|
|
/// 현재 장비 총 무게
|
|
int calculateCurrentWeight(List<Equipment> equipped) {
|
|
return equipped.fold(0, (sum, item) => sum + item.weight);
|
|
}
|
|
|
|
/// 장착 가능 여부
|
|
bool canEquip(Equipment newItem, List<Equipment> current, int str) {
|
|
final maxWeight = calculateMaxWeight(str);
|
|
final currentWeight = calculateCurrentWeight(current);
|
|
final newWeight = currentWeight + newItem.weight;
|
|
return newWeight <= maxWeight;
|
|
}
|
|
}
|
|
```
|
|
|
|
| STR | 최대 무게 | 설명 |
|
|
|-----|----------|------|
|
|
| 10 | 200 | 경장비 + 일부 중장비 |
|
|
| 20 | 300 | 대부분의 장비 |
|
|
| 30 | 400 | 중장비 풀세트 |
|
|
| 50 | 600 | 최중량 장비 |
|
|
|
|
**무게 초과 페널티**: 장착 불가 (자동 장착 시 무게 고려)
|
|
|
|
## 아이템 생성 공식
|
|
|
|
```dart
|
|
/// 아이템 스탯 생성 (레벨 기반)
|
|
ItemStats generateItemStats(int level, ItemRarity rarity, EquipmentSlot slot) {
|
|
final rarityMultiplier = {
|
|
ItemRarity.common: 1.0,
|
|
ItemRarity.uncommon: 1.3,
|
|
ItemRarity.rare: 1.7,
|
|
ItemRarity.epic: 2.2,
|
|
ItemRarity.legendary: 3.0,
|
|
}[rarity]!;
|
|
|
|
final baseValue = (level * 2 * rarityMultiplier).round();
|
|
|
|
// 슬롯별 주요 스탯 결정
|
|
return switch (slot) {
|
|
EquipmentSlot.weapon => ItemStats(atk: baseValue, ...),
|
|
EquipmentSlot.shield => ItemStats(def: baseValue ~/ 2, blockRate: 0.1, ...),
|
|
EquipmentSlot.armor => ItemStats(def: baseValue, ...),
|
|
// ...
|
|
};
|
|
}
|
|
```
|
|
|
|
## 수정 대상 파일
|
|
|
|
| 파일 | 변경 내용 |
|
|
|------|----------|
|
|
| `core/model/game_state.dart` | Equipment 구조 변경, ItemStats 추가 |
|
|
| `core/model/equipment_slot.dart` | 슬롯별 기본 스탯 정의 |
|
|
| `core/util/pq_logic.dart` | 아이템 생성 로직 변경 |
|
|
| `core/engine/item_service.dart` | **신규** - 아이템 관리 전담 |
|
|
| `data/pq_config_data.dart` | 아이템 기본 데이터 확장 |
|
|
|
|
## 예상 작업량
|
|
- 예상 파일 수: 5-6개
|
|
- 신규 코드: ~500 LOC
|
|
- 수정 코드: ~300 LOC
|