Files
maplecontest/docs/superpowers/specs/2026-06-09-shop-rest-design.md
gahusb 03b59eeafc docs(E4): 상점/휴식 설계·구현 계획
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 03:35:05 +09:00

3.7 KiB
Raw Permalink Blame History

상점/휴식 노드 (TODO E4) — 설계

작성: 2026-06-09 / 상태: 승인됨 / 근거: TODO E 분해(E4) + E3 맵 노드 구조. 선행: E3(분기 맵) 완료. 후속: E5(유물)·E6(저장). 카드 제거는 덱 보기 UI 필요 → 후속 분리.

문제

E3로 분기 맵은 됐으나 모든 노드가 전투다. 골드는 적립만 되고 소비처가 없다. 상점(골드→카드)· 휴식(HP 회복) 노드가 필요하다.

범위

맵에 상점/휴식 노드 추가, 진입 시 전투 대신 상점/휴식 UI. 상점 = 카드 구매(골드). 휴식 = HP 회복. 카드 제거(덱 보기 UI 필요)·유물·저장·휴식 업그레이드는 범위 밖.

설계

데이터 (data/map.json 교체 — 4행)

{
  "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 세팅·맵 숨김 후 타입 분기 — shopShowShop, restShowRest, 그 외→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)·휴식 업그레이드·상점 유물/물약.