71 lines
3.7 KiB
Markdown
71 lines
3.7 KiB
Markdown
# 상점/휴식 노드 (TODO E4) — 설계
|
||
|
||
> 작성: 2026-06-09 / 상태: 승인됨 / 근거: TODO E 분해(E4) + E3 맵 노드 구조.
|
||
> 선행: E3(분기 맵) 완료. 후속: E5(유물)·E6(저장). 카드 제거는 덱 보기 UI 필요 → 후속 분리.
|
||
|
||
## 문제
|
||
|
||
E3로 분기 맵은 됐으나 모든 노드가 전투다. 골드는 적립만 되고 소비처가 없다. 상점(골드→카드)·
|
||
휴식(HP 회복) 노드가 필요하다.
|
||
|
||
## 범위
|
||
|
||
맵에 상점/휴식 노드 추가, 진입 시 전투 대신 상점/휴식 UI. 상점 = 카드 구매(골드). 휴식 = HP 회복.
|
||
**카드 제거(덱 보기 UI 필요)·유물·저장·휴식 업그레이드는 범위 밖.**
|
||
|
||
## 설계
|
||
|
||
### 데이터 (`data/map.json` 교체 — 4행)
|
||
```json
|
||
{
|
||
"start": ["A", "B"],
|
||
"nodes": {
|
||
"A": { "type": "combat", "enemy": "slime", "row": 1, "col": -1, "next": ["C", "D"] },
|
||
"B": { "type": "combat", "enemy": "slime", "row": 1, "col": 1, "next": ["C", "D"] },
|
||
"C": { "type": "rest", "row": 2, "col": -1, "next": ["E", "F"] },
|
||
"D": { "type": "shop", "row": 2, "col": 1, "next": ["E", "F"] },
|
||
"E": { "type": "elite", "enemy": "slime_elite", "row": 3, "col": -1, "next": ["BOSS"] },
|
||
"F": { "type": "combat", "enemy": "slime", "row": 3, "col": 1, "next": ["BOSS"] },
|
||
"BOSS": { "type": "boss", "enemy": "slime_boss", "row": 4, "col": 0, "next": [] }
|
||
}
|
||
}
|
||
```
|
||
- rest/shop 노드는 `enemy` 없음. 생성기 검증을 "`enemy` 있을 때만 ENEMIES 확인"으로 완화.
|
||
Lua MapNodes 직렬화도 enemy 있을 때만 `enemy = "..."` 포함.
|
||
|
||
### 파라미터 (생성기 상수)
|
||
- `CARD_PRICE = 30`, `REST_HEAL = 30`.
|
||
|
||
### 상태 추가
|
||
- `ShopChoices`(any) — 상점 제시 카드 id 3개.
|
||
- `ShopBought`(any) — 슬롯별 구매 여부 {bool×3}.
|
||
|
||
### 메서드
|
||
- `PickNode`(수정): CurrentNodeId 세팅·맵 숨김 후 타입 분기 —
|
||
`shop`→`ShowShop`, `rest`→`ShowRest`, 그 외→`CurrentEnemyId=node.enemy`·`StartCombat`.
|
||
- `ShowShop`(신규): 카드 풀에서 3개 무작위→ShopChoices, ShopBought 초기화(false),
|
||
각 슬롯 비주얼·가격·골드 갱신, ShopHud 표시.
|
||
- `BuyCard(slot)`(신규): ShopBought[slot]==true 또는 Gold<CARD_PRICE면 무시. 아니면
|
||
Gold-=CARD_PRICE, RunDeck에 ShopChoices[slot] 추가, ShopBought[slot]=true, 해당 카드 어둡게, 골드 갱신.
|
||
- `ShowRest`(신규): `PlayerHp = min(PlayerMaxHp, PlayerHp + REST_HEAL)`, RestHud에 "HP 옛→새 (+회복)" 표시, RestHud 표시.
|
||
- `LeaveNode`(신규): ShopHud·RestHud 숨김 → `ShowMap`. (상점·휴식 나가기 공용)
|
||
- `RenderShop`(신규): 3 카드 비주얼/가격/구매상태 + 골드 텍스트 갱신.
|
||
|
||
### UI (신규)
|
||
- `ShopHud`(모달, 숨김): 제목 "상점", 골드 텍스트, 카드 3장(sprite+button + Name/Cost/Desc/Price 자식), "나가기" 버튼.
|
||
- `RestHud`(모달, 숨김): 제목 "휴식", 정보 텍스트(런타임), "나가기" 버튼.
|
||
- BindButtons: 상점 카드 버튼 3(→BuyCard i)·상점 나가기(→LeaveNode)·휴식 나가기(→LeaveNode) 바인딩.
|
||
|
||
### MapHud (4행 대응)
|
||
- 노드 y = `(row - (MAX_ROW+1)/2) * 140` (행 수에 맞춰 세로 중앙 정렬). col×180 유지.
|
||
|
||
## 검증 (메이커 Play)
|
||
- 맵→상점(D) 진입 → 카드 3장·가격·골드 표시 → 구매 시 골드 -30·RunDeck +1·해당 카드 비활성 →
|
||
골드 부족 시 구매 무시 → 나가기 → 맵(다음 노드).
|
||
- 맵→휴식(C) 진입 → HP +30(상한 클램프) → 나가기 → 맵.
|
||
- 전투/엘리트/보스/런 클리어/패배 회귀 없음. 생성기 결정적·JSON 유효.
|
||
- (버튼 클릭은 런타임 — MCP는 PickNode/BuyCard/ShowRest/LeaveNode 직접 호출로 검증.)
|
||
|
||
## 범위 밖 (금지)
|
||
- 카드 제거·덱 보기 UI(후속)·유물(E5)·저장(E6)·휴식 업그레이드·상점 유물/물약.
|