5 Commits

Author SHA1 Message Date
5b21e7f436 Merge origin/main (#73 도적 카드 아이콘 + in-combat card picker) into feature/maker-ui-edit
#73이 우리 분기(#72) 이후 main에 머지돼 충돌. 해결:
- 소스(boot·deckturn·deckview·gen-slaydeck·data/cards·legacy/hud/deckall): 자동머지로 통합
  (우리 부트폴링/버튼수정/슬롯추종 + #73 thief 아이콘/card-picker 공존).
- 산출물 ui/DefaultGroup.ui: 우리것(메이커 저작 6 UIGroup) 유지(#73의 옛 단일그룹 생성본 폐기).
- 산출물 SlayDeckController.codeblock: 머지된 소스로 재생성(양쪽 기능 모두 반영).
- card-picker reconcile: #73 새 코드의 옛 경로(/ui/DefaultGroup/DeckAllHud)를
  reconnect-ui-paths로 DeckUIGroup으로 remap + 120카드 ButtonComponent 런타임 부착 wrap.
- 검증: cbgap GAP 0, OpenDebugCardPicker/OnAllDeckCardButton 보존, .ui churn 0, JS 41/41.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:33:37 +09:00
b42d5fcf51 docs: 직업 컨셉 섹션 + deck-concept.md (덱 설계 문서)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:28:44 +09:00
098571e9aa Merge pull request '도적 카드 전체에 공식 스킬 아이콘 적용' (#73) from codex/thief-card-icons into main 2026-06-16 23:20:40 +09:00
ea832ad846 feat(debug): add in-combat card picker 2026-06-16 23:18:16 +09:00
4288c4101b feat(cards): add thief card icons 2026-06-16 23:05:40 +09:00
9 changed files with 407 additions and 99 deletions

View File

@@ -94,6 +94,14 @@ slaymaple/
--- ---
## 직업 컨셉
3직업 모두 Slay the Spire 2 차용 + 메이플 IP 재해석. 카드 덱 상세 설계는 [`docs/deck-concept.md`](docs/deck-concept.md) 참조.
- **⚔️ 전사 (탱커, Ironclad 차용)** — **파이터**: 공격을 *연속*으로 내면 콤보가 쌓이고(방어·파워 등 비공격 카드를 쓰면 콤보 리셋) 콤보로 데미지 증가 버프 = 브루저. **페이지**: 위협 디버프로 버티며 방어도 축적 → **바디 슬램(방어 비례 피해)** 카운터. **스피어맨**: 하이퍼바디·아이언월 유지/리치형.
- **🗡️ 도적 (단검·독, Silent 차용)** — 표창 난사 / 독 / 교활·버림. **어쌔신**(표창·크리·흡혈) / **시프**(단검 난타·독). *형 구현 완료(Silent 88장)*.
- **🔮 법사 (약체·게이지, Defect 차용)** — **위자드(불/독)**: 독을 묻히고 *독 걸린 적에 불 카드 → 추가 데미지*(독뎀 시너지). **위자드(썬/콜)**: 오브로 썬더(다중 공격)·콜드(빙결=취약+피해), 오브 획득·다중 소모 운용. **클레릭**: 오브 없이 회복·버프 + 언데드엔 힐로 공격하는 보조 힐러.
## 게임 프레임워크 현황 ## 게임 프레임워크 현황
**StS2풍 덱빌더 로그라이크가 end-to-end로 완성**됐고, 이제 **로비 마을을 기점으로 반복 런**이 돕니다: **StS2풍 덱빌더 로그라이크가 end-to-end로 완성**됐고, 이제 **로비 마을을 기점으로 반복 런**이 돕니다:
@@ -125,7 +133,7 @@ slaymaple/
| **밸런스 시뮬** | `tools/balance/sim-balance.mjs` — 전투 규칙 JS 미러(몬테카를로) + `tools/map/rogue-map.mjs`(맵 생성 미러) + node 단위테스트 | | **밸런스 시뮬** | `tools/balance/sim-balance.mjs` — 전투 규칙 JS 미러(몬테카를로) + `tools/map/rogue-map.mjs`(맵 생성 미러) + node 단위테스트 |
> ⚠️ 수치(적 스탯·경제·승천 배율)는 1차 조정 상태입니다. 정밀 밸런싱은 `sim-balance.mjs`로 검증하며 진행합니다. > ⚠️ 수치(적 스탯·경제·승천 배율)는 1차 조정 상태입니다. 정밀 밸런싱은 `sim-balance.mjs`로 검증하며 진행합니다.
> 도적(Silent) 카드 88장은 효과·프레임은 적용됐으나 **카드 아이콘(image/fx) 미할당** 상태입니다(전사·마법사 카드는 실 스킬 아이콘 적용 완료). > 도적(Silent) 카드 88장은 STS Silent 완역 포트 + **공식 스킬 아이콘 적용 완료**(PR #73). 남은 작업은 카드명 메이플 재서사(어쌔신/시프)·멀티플레이어 전제 카드 싱글 정리 — [`docs/deck-concept.md`](docs/deck-concept.md) 참조.
### 유용한 스크립트 호출 ### 유용한 스크립트 호출
`/common` 엔티티(또는 Play Test 컨텍스트)에서: `/common` 엔티티(또는 Play Test 컨텍스트)에서:

File diff suppressed because one or more lines are too long

View File

@@ -378,7 +378,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "피해를 3 줍니다. 약화를 1 부여합니다.", "desc": "피해를 3 줍니다. 약화를 1 부여합니다.",
"weak": 1, "weak": 1,
"damage": 3 "damage": 3,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"SilentStrike": { "SilentStrike": {
"name": "타격", "name": "타격",
@@ -387,7 +388,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "피해를 6 줍니다.", "desc": "피해를 6 줍니다.",
"damage": 6 "damage": 6,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"Survivor": { "Survivor": {
"name": "생존자", "name": "생존자",
@@ -397,7 +399,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 8 얻습니다. 카드를 1장 버립니다.", "desc": "방어도를 8 얻습니다. 카드를 1장 버립니다.",
"block": 8, "block": 8,
"discard": 1 "discard": 1,
"image": "49c8f279bfa64bf3954037f17da0052d"
}, },
"SilentDefend": { "SilentDefend": {
"name": "수비", "name": "수비",
@@ -406,7 +409,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 5 얻습니다.", "desc": "방어도를 5 얻습니다.",
"block": 5 "block": 5,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Slice": { "Slice": {
"name": "칼질", "name": "칼질",
@@ -415,7 +419,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "피해를 6 줍니다.", "desc": "피해를 6 줍니다.",
"damage": 6 "damage": 6,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"Shiv": { "Shiv": {
"name": "표창", "name": "표창",
@@ -426,7 +431,8 @@
"desc": "피해를 4 줍니다. 소멸.", "desc": "피해를 4 줍니다. 소멸.",
"damage": 4, "damage": 4,
"exhaust": true, "exhaust": true,
"token": true "token": true,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"DaggerSpray": { "DaggerSpray": {
"name": "단검 분사", "name": "단검 분사",
@@ -437,7 +443,8 @@
"desc": "모든 적에게 피해를 4만큼 2번 줍니다.", "desc": "모든 적에게 피해를 4만큼 2번 줍니다.",
"aoe": true, "aoe": true,
"damage": 4, "damage": 4,
"hits": 2 "hits": 2,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"DaggerThrow": { "DaggerThrow": {
"name": "단검 투척", "name": "단검 투척",
@@ -448,7 +455,8 @@
"desc": "피해를 9 줍니다. 카드를 1장 뽑습니다. 카드를 1장 버립니다.", "desc": "피해를 9 줍니다. 카드를 1장 뽑습니다. 카드를 1장 버립니다.",
"draw": 1, "draw": 1,
"damage": 9, "damage": 9,
"discard": 1 "discard": 1,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"PoisonedStab": { "PoisonedStab": {
"name": "독 찌르기", "name": "독 찌르기",
@@ -458,7 +466,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "피해를 6 줍니다. 중독을 3 부여합니다.", "desc": "피해를 6 줍니다. 중독을 3 부여합니다.",
"poison": 3, "poison": 3,
"damage": 6 "damage": 6,
"image": "19361e72087946b1888684185b40d935"
}, },
"SuckerPunch": { "SuckerPunch": {
"name": "불의의 일격", "name": "불의의 일격",
@@ -468,7 +477,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "피해를 8 줍니다. 약화를 1 부여합니다.", "desc": "피해를 8 줍니다. 약화를 1 부여합니다.",
"weak": 1, "weak": 1,
"damage": 8 "damage": 8,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"LeadingStrike": { "LeadingStrike": {
"name": "선제 타격", "name": "선제 타격",
@@ -478,7 +488,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "피해를 3 줍니다. 표창을 2장 손으로 가져옵니다.", "desc": "피해를 3 줍니다. 표창을 2장 손으로 가져옵니다.",
"damage": 3, "damage": 3,
"addShiv": 2 "addShiv": 2,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"FollowThrough": { "FollowThrough": {
"name": "완수", "name": "완수",
@@ -487,7 +498,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "피해를 7 줍니다. 손에 다른 카드가 5장 이상 있다면, 1번 추가로 적중합니다.", "desc": "피해를 7 줍니다. 손에 다른 카드가 5장 이상 있다면, 1번 추가로 적중합니다.",
"damage": 7 "damage": 7,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"FlickFlack": { "FlickFlack": {
"name": "재주넘기", "name": "재주넘기",
@@ -498,7 +510,8 @@
"desc": "교활. 모든 적에게 피해를 6 줍니다.", "desc": "교활. 모든 적에게 피해를 6 줍니다.",
"aoe": true, "aoe": true,
"damage": 6, "damage": 6,
"sly": true "sly": true,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"Ricochet": { "Ricochet": {
"name": "도탄", "name": "도탄",
@@ -509,7 +522,8 @@
"desc": "교활. 무작위 적에게 피해를 3만큼 4번 줍니다.", "desc": "교활. 무작위 적에게 피해를 3만큼 4번 줍니다.",
"damage": 3, "damage": 3,
"hits": 4, "hits": 4,
"sly": true "sly": true,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"Prepared": { "Prepared": {
"name": "예비", "name": "예비",
@@ -519,7 +533,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "카드를 1장 뽑습니다. 카드를 1장 버립니다.", "desc": "카드를 1장 뽑습니다. 카드를 1장 버립니다.",
"draw": 1, "draw": 1,
"discard": 1 "discard": 1,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"Anticipate": { "Anticipate": {
"name": "예측", "name": "예측",
@@ -528,7 +543,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "이번 턴 동안 민첩을 2 얻습니다.", "desc": "이번 턴 동안 민첩을 2 얻습니다.",
"dex": 2 "dex": 2,
"image": "49c8f279bfa64bf3954037f17da0052d"
}, },
"Deflect": { "Deflect": {
"name": "튕겨내기", "name": "튕겨내기",
@@ -537,7 +553,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 4 얻습니다.", "desc": "방어도를 4 얻습니다.",
"block": 4 "block": 4,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"BladeDance": { "BladeDance": {
"name": "검무", "name": "검무",
@@ -547,7 +564,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "표창을 3장 손으로 가져옵니다. 소멸.", "desc": "표창을 3장 손으로 가져옵니다. 소멸.",
"addShiv": 3, "addShiv": 3,
"exhaust": true "exhaust": true,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"Backflip": { "Backflip": {
"name": "공중제비", "name": "공중제비",
@@ -557,7 +575,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 5 얻습니다. 카드를 2장 뽑습니다.", "desc": "방어도를 5 얻습니다. 카드를 2장 뽑습니다.",
"block": 5, "block": 5,
"draw": 2 "draw": 2,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"DodgeAndRoll": { "DodgeAndRoll": {
"name": "구르기", "name": "구르기",
@@ -566,7 +585,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 4 얻습니다. 다음 턴에, 방어도를 4 얻습니다", "desc": "방어도를 4 얻습니다. 다음 턴에, 방어도를 4 얻습니다",
"block": 4 "block": 4,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"PiercingWail": { "PiercingWail": {
"name": "귀를 찢는 비명", "name": "귀를 찢는 비명",
@@ -575,7 +595,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "이번 턴 동안 모든 적이 힘을 6 잃습니다. 소멸.", "desc": "이번 턴 동안 모든 적이 힘을 6 잃습니다. 소멸.",
"draw": 1 "draw": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"CloakAndDagger": { "CloakAndDagger": {
"name": "망토와 단검", "name": "망토와 단검",
@@ -585,7 +606,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "방어도를 6 얻습니다. 표창을 1장 손으로 가져옵니다.", "desc": "방어도를 6 얻습니다. 표창을 1장 손으로 가져옵니다.",
"block": 6, "block": 6,
"addShiv": 1 "addShiv": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"DeadlyPoison": { "DeadlyPoison": {
"name": "맹독", "name": "맹독",
@@ -594,7 +616,8 @@
"class": "bandit", "class": "bandit",
"rarity": "normal", "rarity": "normal",
"desc": "중독을 5 부여합니다.", "desc": "중독을 5 부여합니다.",
"poison": 5 "poison": 5,
"image": "19361e72087946b1888684185b40d935"
}, },
"Snakebite": { "Snakebite": {
"name": "뱀 물기", "name": "뱀 물기",
@@ -604,7 +627,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "보존. 중독을 7 부여합니다.", "desc": "보존. 중독을 7 부여합니다.",
"poison": 7, "poison": 7,
"retain": true "retain": true,
"image": "19361e72087946b1888684185b40d935"
}, },
"Untouchable": { "Untouchable": {
"name": "범접 불가", "name": "범접 불가",
@@ -614,7 +638,8 @@
"rarity": "normal", "rarity": "normal",
"desc": "교활. 방어도를 6 얻습니다.", "desc": "교활. 방어도를 6 얻습니다.",
"block": 6, "block": 6,
"sly": true "sly": true,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Skewer": { "Skewer": {
"name": "꼬챙이", "name": "꼬챙이",
@@ -623,7 +648,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 8만큼 X번 줍니다.", "desc": "피해를 8만큼 X번 줍니다.",
"draw": 1 "draw": 1,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"Backstab": { "Backstab": {
"name": "배신", "name": "배신",
@@ -632,7 +658,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "선천성. 피해를 11 줍니다. 소멸.", "desc": "선천성. 피해를 11 줍니다. 소멸.",
"damage": 11 "damage": 11,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"PreciseCut": { "PreciseCut": {
"name": "정밀한 베기", "name": "정밀한 베기",
@@ -641,7 +668,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 13 줍니다. 손에 있는 다른 카드 1장당 피해량이 2 감소합니다.", "desc": "피해를 13 줍니다. 손에 있는 다른 카드 1장당 피해량이 2 감소합니다.",
"damage": 13 "damage": 13,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"Finisher": { "Finisher": {
"name": "마무리", "name": "마무리",
@@ -650,7 +678,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "이번 턴에 사용한 공격 카드 1장당 피해를 6 줍니다.", "desc": "이번 턴에 사용한 공격 카드 1장당 피해를 6 줍니다.",
"damage": 6 "damage": 6,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"MementoMori": { "MementoMori": {
"name": "메멘토 모리", "name": "메멘토 모리",
@@ -659,7 +688,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 9 줍니다. 이번 턴에 버린 카드 1장당 피해량이 4 증가합니다.", "desc": "피해를 9 줍니다. 이번 턴에 버린 카드 1장당 피해량이 4 증가합니다.",
"damage": 9 "damage": 9,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Strangle": { "Strangle": {
"name": "목 조르기", "name": "목 조르기",
@@ -668,7 +698,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 8 줍니다. 이번 턴에 카드를 사용할 때마다, 대상 적이 체력을 2 잃습니다.", "desc": "피해를 8 줍니다. 이번 턴에 카드를 사용할 때마다, 대상 적이 체력을 2 잃습니다.",
"damage": 8 "damage": 8,
"image": "92a5020c978c46bdabab910598118b86"
}, },
"Flechettes": { "Flechettes": {
"name": "프레췌", "name": "프레췌",
@@ -677,7 +708,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "손에 있는 스킬 카드 1장당 피해를 5 줍니다.", "desc": "손에 있는 스킬 카드 1장당 피해를 5 줍니다.",
"damage": 5 "damage": 5,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"Pounce": { "Pounce": {
"name": "덮치기", "name": "덮치기",
@@ -686,7 +718,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 12 줍니다. 다음에 사용하는 스킬 카드의 비용이 0 이 됩니다.", "desc": "피해를 12 줍니다. 다음에 사용하는 스킬 카드의 비용이 0 이 됩니다.",
"damage": 12 "damage": 12,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"Dash": { "Dash": {
"name": "돌진", "name": "돌진",
@@ -696,7 +729,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "방어도를 10 얻습니다. 피해를 10 줍니다.", "desc": "방어도를 10 얻습니다. 피해를 10 줍니다.",
"block": 10, "block": 10,
"damage": 10 "damage": 10,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"Predator": { "Predator": {
"name": "천적", "name": "천적",
@@ -706,7 +740,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "피해를 15 줍니다. 다음 턴에, 카드를 2장 뽑습니다.", "desc": "피해를 15 줍니다. 다음 턴에, 카드를 2장 뽑습니다.",
"draw": 2, "draw": 2,
"damage": 15 "damage": 15,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"Pinpoint": { "Pinpoint": {
"name": "정밀 사격", "name": "정밀 사격",
@@ -715,7 +750,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "피해를 15 줍니다. 이번 턴에 스킬을 사용할 때마다 비용이 1 감소합니다.", "desc": "피해를 15 줍니다. 이번 턴에 스킬을 사용할 때마다 비용이 1 감소합니다.",
"damage": 15 "damage": 15,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"CalculatedGamble": { "CalculatedGamble": {
"name": "계산된 도박", "name": "계산된 도박",
@@ -724,7 +760,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "손에 있는 모든 카드를 버린 뒤, 버린 카드의 수만큼 카드를 뽑습니다. 소멸.", "desc": "손에 있는 모든 카드를 버린 뒤, 버린 카드의 수만큼 카드를 뽑습니다. 소멸.",
"draw": 1 "draw": 1,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"Expose": { "Expose": {
"name": "들춰내기", "name": "들춰내기",
@@ -733,7 +770,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "대상 적의 모든 인공물과 방어도를 제거합니다. 취약을 2 부여합니다. 소멸.", "desc": "대상 적의 모든 인공물과 방어도를 제거합니다. 취약을 2 부여합니다. 소멸.",
"vuln": 2 "vuln": 2,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"HiddenDaggers": { "HiddenDaggers": {
"name": "숨겨진 단검", "name": "숨겨진 단검",
@@ -743,7 +781,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "카드를 2장 버립니다. 표창을 2장 손으로 가져옵니다.", "desc": "카드를 2장 버립니다. 표창을 2장 손으로 가져옵니다.",
"discard": 2, "discard": 2,
"addShiv": 2 "addShiv": 2,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"EscapePlan": { "EscapePlan": {
"name": "탈출구", "name": "탈출구",
@@ -753,7 +792,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "카드를 1장 뽑습니다. 뽑은 카드가 스킬 카드라면, 방어도를 3 얻습니다.", "desc": "카드를 1장 뽑습니다. 뽑은 카드가 스킬 카드라면, 방어도를 3 얻습니다.",
"block": 3, "block": 3,
"draw": 1 "draw": 1,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"Acrobatics": { "Acrobatics": {
"name": "곡예", "name": "곡예",
@@ -763,7 +803,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "카드를 3장 뽑습니다. 카드를 1장 버립니다.", "desc": "카드를 3장 뽑습니다. 카드를 1장 버립니다.",
"draw": 3, "draw": 3,
"discard": 1 "discard": 1,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"HandTrick": { "HandTrick": {
"name": "손기술", "name": "손기술",
@@ -772,7 +813,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "방어도를 7 얻습니다. 이번 턴 동안 손에 있는 스킬 카드 1장에 교활을 추가합니다.", "desc": "방어도를 7 얻습니다. 이번 턴 동안 손에 있는 스킬 카드 1장에 교활을 추가합니다.",
"block": 7 "block": 7,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"Mirage": { "Mirage": {
"name": "신기루", "name": "신기루",
@@ -781,7 +823,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "모든 적에게 부여된 중독과 동일한 만큼의 방어도를 얻습니다. 소멸.", "desc": "모든 적에게 부여된 중독과 동일한 만큼의 방어도를 얻습니다. 소멸.",
"draw": 1 "draw": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Expertise": { "Expertise": {
"name": "전문성", "name": "전문성",
@@ -790,7 +833,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "손에 있는 카드가 6장이 될 때까지 카드를 뽑습니다.", "desc": "손에 있는 카드가 6장이 될 때까지 카드를 뽑습니다.",
"draw": 1 "draw": 1,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"BubbleBubble": { "BubbleBubble": {
"name": "차오르는 독", "name": "차오르는 독",
@@ -799,7 +843,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "적이 중독을 보유하고 있다면, 중독을 9 부여합니다.", "desc": "적이 중독을 보유하고 있다면, 중독을 9 부여합니다.",
"poison": 9 "poison": 9,
"image": "19361e72087946b1888684185b40d935"
}, },
"Blur": { "Blur": {
"name": "흐릿함", "name": "흐릿함",
@@ -808,7 +853,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "방어도를 5 얻습니다. 다음 턴 시작 시 방어도가 사라지지 않습니다.", "desc": "방어도를 5 얻습니다. 다음 턴 시작 시 방어도가 사라지지 않습니다.",
"block": 5 "block": 5,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"LegSweep": { "LegSweep": {
"name": "다리 걸기", "name": "다리 걸기",
@@ -818,7 +864,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "약화를 2 부여합니다. 방어도를 11 얻습니다.", "desc": "약화를 2 부여합니다. 방어도를 11 얻습니다.",
"block": 11, "block": 11,
"weak": 2 "weak": 2,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"UpMySleeve": { "UpMySleeve": {
"name": "비책", "name": "비책",
@@ -827,7 +874,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "표창을 3장 손으로 가져옵니다. 이 카드의 비용이 1 감소합니다.", "desc": "표창을 3장 손으로 가져옵니다. 이 카드의 비용이 1 감소합니다.",
"addShiv": 3 "addShiv": 3,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"BouncingFlask": { "BouncingFlask": {
"name": "탄성 플라스크", "name": "탄성 플라스크",
@@ -836,7 +884,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "무작위 적에게 중독을 3만큼 3번 부여합니다.", "desc": "무작위 적에게 중독을 3만큼 3번 부여합니다.",
"poison": 9 "poison": 9,
"image": "19361e72087946b1888684185b40d935"
}, },
"Reflex": { "Reflex": {
"name": "반사신경", "name": "반사신경",
@@ -846,7 +895,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "교활. 카드를 2장 뽑습니다.", "desc": "교활. 카드를 2장 뽑습니다.",
"draw": 2, "draw": 2,
"sly": true "sly": true,
"image": "49c8f279bfa64bf3954037f17da0052d"
}, },
"Haze": { "Haze": {
"name": "아지랑이", "name": "아지랑이",
@@ -856,7 +906,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "교활. 모든 적에게 중독을 4 부여합니다.", "desc": "교활. 모든 적에게 중독을 4 부여합니다.",
"poison": 4, "poison": 4,
"sly": true "sly": true,
"image": "19361e72087946b1888684185b40d935"
}, },
"Tactician": { "Tactician": {
"name": "전략가", "name": "전략가",
@@ -867,7 +918,8 @@
"desc": "교활. 을 얻습니다.", "desc": "교활. 을 얻습니다.",
"powerEffect": "energyPerTurn", "powerEffect": "energyPerTurn",
"value": 1, "value": 1,
"sly": true "sly": true,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"WellLaidPlans": { "WellLaidPlans": {
"name": "괜찮은 전략", "name": "괜찮은 전략",
@@ -877,7 +929,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "내 턴 종료 시, 카드를 최대 1장까지 보존합니다.", "desc": "내 턴 종료 시, 카드를 최대 1장까지 보존합니다.",
"powerEffect": "blockPerTurn", "powerEffect": "blockPerTurn",
"value": 2 "value": 2,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"InfiniteBlades": { "InfiniteBlades": {
"name": "무한의 검날", "name": "무한의 검날",
@@ -886,7 +939,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "내 턴 시작 시, 표창을 1장 손으로 가져옵니다.", "desc": "내 턴 시작 시, 표창을 1장 손으로 가져옵니다.",
"turnStartShiv": 1 "turnStartShiv": 1,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"Footwork": { "Footwork": {
"name": "발놀림", "name": "발놀림",
@@ -895,7 +949,8 @@
"class": "bandit", "class": "bandit",
"rarity": "unique", "rarity": "unique",
"desc": "민첩을 2 얻습니다.", "desc": "민첩을 2 얻습니다.",
"dex": 2 "dex": 2,
"image": "49c8f279bfa64bf3954037f17da0052d"
}, },
"Outbreak": { "Outbreak": {
"name": "발병", "name": "발병",
@@ -907,7 +962,8 @@
"aoe": true, "aoe": true,
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1, "value": 1,
"damage": 11 "damage": 11,
"image": "19361e72087946b1888684185b40d935"
}, },
"NoxiousFumes": { "NoxiousFumes": {
"name": "유독 가스", "name": "유독 가스",
@@ -918,7 +974,8 @@
"desc": "내 턴 시작 시, 모든 적에게 중독을 2 부여합니다.", "desc": "내 턴 시작 시, 모든 적에게 중독을 2 부여합니다.",
"poison": 2, "poison": 2,
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "19361e72087946b1888684185b40d935"
}, },
"Accuracy": { "Accuracy": {
"name": "정밀", "name": "정밀",
@@ -928,7 +985,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "표창의 피해량이 4 증가합니다.", "desc": "표창의 피해량이 4 증가합니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"PhantomBlades": { "PhantomBlades": {
"name": "환영검", "name": "환영검",
@@ -938,7 +996,8 @@
"rarity": "unique", "rarity": "unique",
"desc": "표창이 보존을 얻습니다. 매 턴마다 처음으로 사용하는 표창의 피해량이 9 증가합니다.", "desc": "표창이 보존을 얻습니다. 매 턴마다 처음으로 사용하는 표창의 피해량이 9 증가합니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Speedster": { "Speedster": {
"name": "스피드스터", "name": "스피드스터",
@@ -950,7 +1009,8 @@
"aoe": true, "aoe": true,
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1, "value": 1,
"damage": 2 "damage": 2,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"GrandFinale": { "GrandFinale": {
"name": "대단원의 막", "name": "대단원의 막",
@@ -960,7 +1020,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "뽑을 카드 더미에 카드가 없을 때만 사용할 수 있습니다. 모든 적에게 피해를 60 줍니다.", "desc": "뽑을 카드 더미에 카드가 없을 때만 사용할 수 있습니다. 모든 적에게 피해를 60 줍니다.",
"aoe": true, "aoe": true,
"damage": 60 "damage": 60,
"image": "dbdbb1b56ae54672ae68ac6882fff6a2"
}, },
"Assassinate": { "Assassinate": {
"name": "암살", "name": "암살",
@@ -970,7 +1031,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "선천성. 피해를 10 줍니다. 취약을 1 부여합니다. 소멸.", "desc": "선천성. 피해를 10 줍니다. 취약을 1 부여합니다. 소멸.",
"vuln": 1, "vuln": 1,
"damage": 10 "damage": 10,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"EchoingSlash": { "EchoingSlash": {
"name": "메아리 참격", "name": "메아리 참격",
@@ -980,7 +1042,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "모든 적에게 피해를 10 줍니다. 적을 처치할 때마다 이 효과를 반복합니다.", "desc": "모든 적에게 피해를 10 줍니다. 적을 처치할 때마다 이 효과를 반복합니다.",
"aoe": true, "aoe": true,
"damage": 10 "damage": 10,
"image": "dbdbb1b56ae54672ae68ac6882fff6a2"
}, },
"TheHunt": { "TheHunt": {
"name": "사냥", "name": "사냥",
@@ -989,7 +1052,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "피해를 10 줍니다. 치명타라면, 카드 보상을 추가로 얻습니다. 소멸.", "desc": "피해를 10 줍니다. 치명타라면, 카드 보상을 추가로 얻습니다. 소멸.",
"damage": 10 "damage": 10,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"Murder": { "Murder": {
"name": "살해", "name": "살해",
@@ -998,7 +1062,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "피해를 1 줍니다. 이번 전투 동안 뽑은 카드 1장당 피해량이 1 증가합니다.", "desc": "피해를 1 줍니다. 이번 전투 동안 뽑은 카드 1장당 피해량이 1 증가합니다.",
"damage": 1 "damage": 1,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"Malaise": { "Malaise": {
"name": "불쾌", "name": "불쾌",
@@ -1007,7 +1072,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "적이 힘을 X 잃습니다. 약화를 X 부여합니다. 소멸.", "desc": "적이 힘을 X 잃습니다. 약화를 X 부여합니다. 소멸.",
"weak": 3 "weak": 3,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Adrenaline": { "Adrenaline": {
"name": "아드레날린", "name": "아드레날린",
@@ -1018,7 +1084,8 @@
"desc": "를 얻습니다. 카드를 2장 뽑습니다. 소멸.", "desc": "를 얻습니다. 카드를 2장 뽑습니다. 소멸.",
"draw": 2, "draw": 2,
"powerEffect": "energyPerTurn", "powerEffect": "energyPerTurn",
"value": 1 "value": 1,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"StormOfSteel": { "StormOfSteel": {
"name": "강철의 폭풍", "name": "강철의 폭풍",
@@ -1028,7 +1095,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "손에 있는 모든 카드를 버립니다. 버린 카드의 수만큼 표창을 손으로 가져옵니다.", "desc": "손에 있는 모든 카드를 버립니다. 버린 카드의 수만큼 표창을 손으로 가져옵니다.",
"discardAll": true, "discardAll": true,
"addShivPerDiscard": true "addShivPerDiscard": true,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"ShadowStep": { "ShadowStep": {
"name": "그림자 걸음", "name": "그림자 걸음",
@@ -1038,7 +1106,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "손에 있는 모든 카드를 버립니다. 다음 턴에, 공격 카드의 피해량이 2배가 됩니다.", "desc": "손에 있는 모든 카드를 버립니다. 다음 턴에, 공격 카드의 피해량이 2배가 됩니다.",
"draw": 1, "draw": 1,
"discardAll": true "discardAll": true,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Shadowmeld": { "Shadowmeld": {
"name": "그림자 은신", "name": "그림자 은신",
@@ -1047,7 +1116,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "이번 턴 동안 얻는 방어도가 2배가 됩니다.", "desc": "이번 턴 동안 얻는 방어도가 2배가 됩니다.",
"draw": 1 "draw": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"CorrosiveWave": { "CorrosiveWave": {
"name": "부식성 파도", "name": "부식성 파도",
@@ -1056,7 +1126,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "이번 턴에 카드를 뽑을 때마다, 모든 적에게 중독을 2 부여합니다.", "desc": "이번 턴에 카드를 뽑을 때마다, 모든 적에게 중독을 2 부여합니다.",
"poison": 2 "poison": 2,
"image": "19361e72087946b1888684185b40d935"
}, },
"BladeOfInk": { "BladeOfInk": {
"name": "잉크 칼날", "name": "잉크 칼날",
@@ -1065,7 +1136,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "잉크투성이 표창을 2장 손으로 가져옵니다.", "desc": "잉크투성이 표창을 2장 손으로 가져옵니다.",
"addShiv": 2 "addShiv": 2,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"Burst": { "Burst": {
"name": "폭주", "name": "폭주",
@@ -1074,7 +1146,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "이번 턴에 다음에 사용하는 스킬 카드가 1번 추가로 사용됩니다.", "desc": "이번 턴에 다음에 사용하는 스킬 카드가 1번 추가로 사용됩니다.",
"draw": 1 "draw": 1,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"KnifeTrap": { "KnifeTrap": {
"name": "칼날 함정", "name": "칼날 함정",
@@ -1083,7 +1156,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "대상 적에게 소멸된 카드 더미에 있는 모든 표창을 사용합니다.", "desc": "대상 적에게 소멸된 카드 더미에 있는 모든 표창을 사용합니다.",
"draw": 1 "draw": 1,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"BulletTime": { "BulletTime": {
"name": "불릿 타임", "name": "불릿 타임",
@@ -1093,7 +1167,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "이번 턴 동안 더 이상 카드를 뽑을 수 없습니다. 이번 턴 동안 손에 있는 모든 카드를 비용 없이 사용할 수 있습니다.", "desc": "이번 턴 동안 더 이상 카드를 뽑을 수 없습니다. 이번 턴 동안 손에 있는 모든 카드를 비용 없이 사용할 수 있습니다.",
"powerEffect": "energyPerTurn", "powerEffect": "energyPerTurn",
"value": 1 "value": 1,
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
}, },
"Nightmare": { "Nightmare": {
"name": "악몽", "name": "악몽",
@@ -1102,7 +1177,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "카드를 1장 선택합니다. 다음 턴에, 그 카드의 복사본을 3장 손으로 가져옵니다. 소멸.", "desc": "카드를 1장 선택합니다. 다음 턴에, 그 카드의 복사본을 3장 손으로 가져옵니다. 소멸.",
"draw": 1 "draw": 1,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"ToolsOfTheTrade": { "ToolsOfTheTrade": {
"name": "작업 도구", "name": "작업 도구",
@@ -1114,7 +1190,8 @@
"draw": 1, "draw": 1,
"powerEffect": "energyPerTurn", "powerEffect": "energyPerTurn",
"value": 1, "value": 1,
"discard": 1 "discard": 1,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"Afterimage": { "Afterimage": {
"name": "잔상", "name": "잔상",
@@ -1125,7 +1202,8 @@
"desc": "카드를 사용할 때마다, 방어도를 1 얻습니다.", "desc": "카드를 사용할 때마다, 방어도를 1 얻습니다.",
"block": 1, "block": 1,
"powerEffect": "blockPerTurn", "powerEffect": "blockPerTurn",
"value": 2 "value": 2,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Accelerant": { "Accelerant": {
"name": "촉진제", "name": "촉진제",
@@ -1135,7 +1213,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "중독이 1번 추가로 발동합니다.", "desc": "중독이 1번 추가로 발동합니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "19361e72087946b1888684185b40d935"
}, },
"Envenom": { "Envenom": {
"name": "독 바르기", "name": "독 바르기",
@@ -1146,7 +1225,8 @@
"desc": "공격 카드가 막히지 않은 피해를 줄 때마다, 중독을 1 부여합니다.", "desc": "공격 카드가 막히지 않은 피해를 줄 때마다, 중독을 1 부여합니다.",
"poison": 1, "poison": 1,
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "19361e72087946b1888684185b40d935"
}, },
"MasterPlanner": { "MasterPlanner": {
"name": "설계의 대가", "name": "설계의 대가",
@@ -1156,7 +1236,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "스킬 카드를 사용 시, 그 카드가 교활을 얻습니다.", "desc": "스킬 카드를 사용 시, 그 카드가 교활을 얻습니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "c1e19219745e44c39ae6ac2f77e347d9"
}, },
"Tracking": { "Tracking": {
"name": "추적", "name": "추적",
@@ -1166,7 +1247,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "약화 상태의 적이 공격 카드로 받는 피해가 2배가 됩니다.", "desc": "약화 상태의 적이 공격 카드로 받는 피해가 2배가 됩니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1 "value": 1,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"FanOfKnives": { "FanOfKnives": {
"name": "칼날 부채", "name": "칼날 부채",
@@ -1177,7 +1259,8 @@
"desc": "표창이 이제 모든 적을 대상으로 합니다. 표창을 4장 손으로 가져옵니다.", "desc": "표창이 이제 모든 적을 대상으로 합니다. 표창을 4장 손으로 가져옵니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1, "value": 1,
"addShiv": 4 "addShiv": 4,
"image": "1b0f2dc8abd0434990eee1befefcbe0d"
}, },
"SerpentForm": { "SerpentForm": {
"name": "구렁이의 형상", "name": "구렁이의 형상",
@@ -1188,7 +1271,8 @@
"desc": "카드를 사용할 때마다, 무작위 적에게 피해를 4 줍니다.", "desc": "카드를 사용할 때마다, 무작위 적에게 피해를 4 줍니다.",
"powerEffect": "strengthPerTurn", "powerEffect": "strengthPerTurn",
"value": 1, "value": 1,
"damage": 4 "damage": 4,
"image": "19361e72087946b1888684185b40d935"
}, },
"Abrasive": { "Abrasive": {
"name": "연마", "name": "연마",
@@ -1199,7 +1283,8 @@
"desc": "교활. 민첩을 1 얻습니다. 가시를 4 얻습니다.", "desc": "교활. 민첩을 1 얻습니다. 가시를 4 얻습니다.",
"dex": 1, "dex": 1,
"thorns": 4, "thorns": 4,
"sly": true "sly": true,
"image": "49c8f279bfa64bf3954037f17da0052d"
}, },
"Suppress": { "Suppress": {
"name": "진압", "name": "진압",
@@ -1209,7 +1294,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "선천성. 피해를 11 줍니다. 약화를 3 부여합니다.", "desc": "선천성. 피해를 11 줍니다. 약화를 3 부여합니다.",
"weak": 3, "weak": 3,
"damage": 11 "damage": 11,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"WraithForm": { "WraithForm": {
"name": "유령의 형상", "name": "유령의 형상",
@@ -1219,7 +1305,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "불가침을 2 얻습니다. 내 턴 종료 시 민첩을 1 잃습니다.", "desc": "불가침을 2 얻습니다. 내 턴 종료 시 민첩을 1 잃습니다.",
"powerEffect": "blockPerTurn", "powerEffect": "blockPerTurn",
"value": 8 "value": 8,
"image": "0946f69d84464df29b24b94c744c868d"
}, },
"Flanking": { "Flanking": {
"name": "측면 공격", "name": "측면 공격",
@@ -1228,7 +1315,8 @@
"class": "bandit", "class": "bandit",
"rarity": "legend", "rarity": "legend",
"desc": "이번 턴에 대상 적이 다른 플레이어에게 받는 피해량이 2배가 됩니다.", "desc": "이번 턴에 대상 적이 다른 플레이어에게 받는 피해량이 2배가 됩니다.",
"draw": 1 "draw": 1,
"image": "b1360ed0c4b942309d240634b8f36872"
}, },
"Sneaky": { "Sneaky": {
"name": "비열함", "name": "비열함",
@@ -1238,7 +1326,8 @@
"rarity": "legend", "rarity": "legend",
"desc": "교활. 다른 플레이어가 적을 공격할 때마다, 방어도를 1 얻습니다.", "desc": "교활. 다른 플레이어가 적을 공격할 때마다, 방어도를 1 얻습니다.",
"block": 1, "block": 1,
"sly": true "sly": true,
"image": "0946f69d84464df29b24b94c744c868d"
} }
}, },
"starterDecks": { "starterDecks": {

86
docs/deck-concept.md Normal file
View File

@@ -0,0 +1,86 @@
# SlayMaple 덱 컨셉 & 직업 스킬셋
> SlayMaple 카드 덱의 **직업별 컨셉 · 메이플 스킬셋 · Slay the Spire 2 차용 매칭** 설계 문서.
> 원칙: 카드 한 장 = **STS2 메커니즘(뼈대) + 메이플 스킬(외형)**. STS 고유 *표현*(카드명·아트·UI)은 모방 금지, *메커니즘*만 차용(IP 해석 심사 대비).
> 수치(데미지·코스트·등급)는 `tools/balance/sim-balance.mjs`로 검증. 본 문서는 *어떤 스킬을 어떤 카드로* 만들지의 설계도.
기준: 메이플 = **클래식(빅뱅 이전)** 스킬 외형, STS = **Slay the Spire 2**.
---
## 직업 ↔ STS2 매칭 요약
| 직업 | 컨셉 | STS2 차용 |
|---|---|---|
| ⚔️ 전사 | 단단한 탱커/브루저 | The Ironclad (힘·방어·소멸) |
| 🗡️ 도적 | 단검 난사 / 독 | The Silent (표창·독·교활) |
| 🔮 법사 | 약체 + 게이지 운용 | The Defect (오브·집중) |
---
## ⚔️ 전사 (Warrior) — HP80 · 탱커
방어를 쌓고 버티다 역공하는 브루저. Ironclad의 두 축을 2차 전직으로 분화.
### 파이터 — 콤보 브루저형 탱커
- **콤보 규칙**: 공격 카드를 **연속으로** 사용하면 콤보가 쌓인다. **방어·파워 등 비공격(Skill/Power) 카드를 사용하면 콤보가 리셋(0)** 된다.
- 콤보가 쌓일수록 **데미지 증가 버프(힘 계열)** 를 받는다 → 방어를 포기하고 공격을 몰아칠수록 강해지는 리스크/리워드.
- 차용: Ironclad 힘 스택/Demon Form + 콤보. 메이플 외형: 콤보 어택·분노·브랜디시.
### 페이지 — 방어 축적 → 바디 슬램 카운터
- **위협**(전체 적 약화+취약 디버프)로 버티며 **방어도를 축적**(아이언 월 등 + 방어 유지 retain).
- **바디 슬램**: 현재 방어도에 비례한 피해로 카운터. 파워 가드(반사) 보조.
- 차용: Ironclad 방어 빌드(Barricade+Entrench→Body Slam). 메이플 외형: 위협·아이언 월·파워 가드.
### 스피어맨 — 유지/리치형
- 하이퍼 바디(최대 HP↑)·아이언 월(방어 유지)·창 리치 광역. 공격 스케일(파이터)·방어 카운터(페이지)와 구분되는 지속 탱.
---
## 🗡️ 도적 (Thief) — HP70 · 단검/독
Slay the Spire *Silent* 차용. **형(codex)이 Silent 88장 완역 포트 + 스킬 아이콘 적용 완료.** 3대 아키타입:
- **표창(Shiv) 난사**: 0코스트 표창 토큰 대량 생성 → 공격마다 연계. (정밀=표창 피해↑, 칼날 부채=표창 전체화)
- **독(Poison)**: 중독 중첩 → 매턴 틱뎀. (유독 가스·발병·촉진제·독 바르기)
- **교활(Sly)·버림(discard)**: 버려질 때 무료 발동, 얇은 덱 빠른 순환.
### 2차 갈래
- **어쌔신** — 표창 난사 + 크리 / 흡혈(드레인) 중심.
- **시프** — 단검 난타(새비지 블로우 = 다단히트) + 독 / 버림 중심.
> 남은 작업: 카드명이 STS 직역(무력화·배신·아드레날린 등) → **어쌔신/시프 메이플 스킬명으로 재서사** + 멀티플레이어 전제 카드(측면 공격·비열함·추적) 싱글 출품용 정리.
---
## 🔮 법사 (Magician) — HP70 · 약체/게이지
몸은 약하나 **게이지(오브) 운용**으로 다중 공격·화력 집중. **오브 메커니즘은 위자드(불/독·썬/콜)에만 적용**, 클레릭은 별도 보조 컨셉.
### 위자드(불/독) — 독 + 불 시너지
- **독을 묻히는 스킬**(포이즌 브레스 등)으로 대상에 독을 부여(독뎀 = DoT).
- **독이 묻은 적에게 불 카드(파이어 애로우 등)를 쓰면 추가 데미지** — *독뎀 상수* 보너스(독 스택/상수 비례).
- 즉 "독 깔기 → 불로 폭발"의 2단 콤보. 불·독 오브로 운용.
### 위자드(썬/콜) — 오브 운용(썬더 다중 / 콜드 빙결)
- **오브로 썬더·콜드를 보유**. **썬더 = 다중 공격 특화**(AoE·다단). **콜드 = 빙결 부여**(빙결 = *취약과 동일 효과* 를 데미지와 함께).
- **오브를 사용하는 만큼 오브를 획득하거나 다중 소모**하는 방식 — 오브 수급/소비 운용이 핵심.
### 클레릭 — 보조(회복·버프) · 오브 없음
- **회복 스킬**(힐)과 **각종 버프**(블레스 등) 중심의 서포트.
- **언데드 계열 몬스터에게는 힐로 공격** 가능 — 보조 힐러 정체성.
> ⚠️ 위자드 오브/게이지·전사 콤보 스택·바디 슬램·독뎀 시너지는 **신규 메커니즘** — `tools/deck/gen-slaydeck.mjs`(전투 규칙) + `tools/balance/sim-balance.mjs`(JS 미러) 양쪽 구현·동기화 필요.
---
## 차용 경계 (IP 심사 대비)
- 차용 OK = **메커니즘**(콤보 스택·방어→피해 전환·독+불 시너지·오브 게이지·빙결=취약 등 시스템).
- 모방 금지 = STS 고유 **표현**(카드명·아트·UI 직접 사용).
- 만점 루트 = STS2 메커니즘을 **메이플 스킬·외형으로 완전 재서사화**.
## 참고
- 카드 데이터 단일 소스: `data/cards.json` (현 122장: 전사 18·마법사 14·도적 88 + Shiv·저주)
- 메이플 스킬 외형 매핑·STS2 캐릭터 상세는 박재오 개인 위키 `프로젝트-메이플-덱빌딩-스킬구성` / `프로젝트-메이플-STS2-차용-덱컨셉` 참조.

View File

@@ -29,10 +29,24 @@ if lp ~= nil then
end end
_InputService:ConnectEvent(KeyDownEvent, function(e) _InputService:ConnectEvent(KeyDownEvent, function(e)
if e.key == KeyboardKey.LeftControl then if e.key == KeyboardKey.LeftControl then
self.DebugCtrlDown = true
local lp2 = _UserService.LocalPlayer local lp2 = _UserService.LocalPlayer
if lp2 ~= nil and lp2.CurrentMapName == "${LOBBY_MAP}" and self.RunActive ~= true then if lp2 ~= nil and lp2.CurrentMapName == "${LOBBY_MAP}" and self.RunActive ~= true then
self:PlayerAttackMotion() self:PlayerAttackMotion()
end end
elseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then
self.DebugShiftDown = true
elseif e.key == KeyboardKey.C then
if self.DebugCtrlDown == true and self.DebugShiftDown == true then
self:OpenDebugCardPicker()
end
end
end)
_InputService:ConnectEvent(KeyUpEvent, function(e)
if e.key == KeyboardKey.LeftControl then
self.DebugCtrlDown = false
elseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then
self.DebugShiftDown = false
end end
end)`), end)`),
method('ReqLoadAscension', `local ds = _DataStorageService:GetUserDataStorage(userId) method('ReqLoadAscension', `local ds = _DataStorageService:GetUserDataStorage(userId)

View File

@@ -67,6 +67,13 @@ if allDeckClose ~= nil and (allDeckClose.ButtonComponent ~= nil or allDeckClose:
self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end) self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
end end
self:BindClassDeckTabs() self:BindClassDeckTabs()
for i = 1, 120 do
local allCard = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. tostring(i))
if allCard ~= nil and (allCard.ButtonComponent ~= nil or allCard:AddComponent("ButtonComponent") ~= nil) then
local slot = i
allCard:ConnectEvent(ButtonClickEvent, function() self:OnAllDeckCardButton(slot) end)
end
end
for i = 1, 10 do for i = 1, 10 do
local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i)) local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i))
if cardEntity ~= nil and cardEntity.UITouchReceiveComponent ~= nil then if cardEntity ~= nil and cardEntity.UITouchReceiveComponent ~= nil then

View File

@@ -94,12 +94,31 @@ if mageTab ~= nil and (mageTab.ButtonComponent ~= nil or mageTab:AddComponent("B
end`), end`),
method('OpenClassDeck', `self.CodexMode = false method('OpenClassDeck', `self.CodexMode = false
self.ClassDeckMode = true self.ClassDeckMode = true
self.DebugCardPickerMode = false
self.DeckAllOpen = true self.DeckAllOpen = true
self:SetClassDeckTab(className) self:SetClassDeckTab(className)
local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud") local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud")
if hud ~= nil then if hud ~= nil then
hud.Enable = true hud.Enable = true
end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'className' }]), end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'className' }]),
method('OpenDebugCardPicker', `if self.RunActive ~= true or self.CombatOver == true or self.Hand == nil then
self:Toast("전투 중에만 테스트 카드를 추가할 수 있습니다")
return
end
local className = self.SelectedClass
if className ~= "warrior" and className ~= "magician" and className ~= "bandit" then
className = "bandit"
end
self.CodexMode = false
self.ClassDeckMode = true
self.DebugCardPickerMode = true
self.DeckAllOpen = true
self:SetClassDeckTab(className)
local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud")
if hud ~= nil then
hud.Enable = true
end
self:Toast("테스트 카드 추가 모드")`),
method('SetClassDeckTab', `if self.ClassDeckMode ~= true then method('SetClassDeckTab', `if self.ClassDeckMode ~= true then
return return
end end
@@ -171,6 +190,7 @@ end
self.DeckInspectKind = "" self.DeckInspectKind = ""
self.ClassDeckMode = false self.ClassDeckMode = false
self.ClassDeckClass = "" self.ClassDeckClass = ""
self.DebugCardPickerMode = false
self:RenderClassDeckTabs() self:RenderClassDeckTabs()
self.DeckAllOpen = true self.DeckAllOpen = true
self:RenderAllDeck() self:RenderAllDeck()
@@ -189,6 +209,7 @@ if self.ClassDeckMode == true then
self.ClassDeckTitle = "" self.ClassDeckTitle = ""
self.ClassDeckClass = "" self.ClassDeckClass = ""
end end
self.DebugCardPickerMode = false
self:RenderClassDeckTabs() self:RenderClassDeckTabs()
if self.CodexMode == true then if self.CodexMode == true then
self.CodexMode = false self.CodexMode = false
@@ -199,6 +220,9 @@ local title = "모든 덱"
if self.ClassDeckMode == true then if self.ClassDeckMode == true then
pile = self.ClassDeckCards or {} pile = self.ClassDeckCards or {}
title = self.ClassDeckTitle title = self.ClassDeckTitle
if self.DebugCardPickerMode == true then
title = title .. " - 테스트 카드 추가"
end
elseif self.CodexMode == true then elseif self.CodexMode == true then
pile = self.CodexCards or {} pile = self.CodexCards or {}
title = "카드 도감" title = "카드 도감"
@@ -226,4 +250,21 @@ end`),
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }, { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' }, { Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
]), ]),
method('OnAllDeckCardButton', `if self.DebugCardPickerMode ~= true then
return
end
if self.ClassDeckCards == nil then
return
end
local cardId = self.ClassDeckCards[slot]
if cardId == nil or self.Cards == nil or self.Cards[cardId] == nil then
return
end
self:AddCardsToHand(cardId, 1)
local c = self.Cards[cardId]
local name = cardId
if c.name ~= nil then name = c.name end
self:Toast("테스트 카드 추가: " .. name)`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
]),
]; ];

View File

@@ -62,6 +62,9 @@ function writeCodeblocks() {
prop('boolean', 'CodexMode', 'false'), prop('boolean', 'CodexMode', 'false'),
prop('any', 'CodexCards'), prop('any', 'CodexCards'),
prop('boolean', 'ClassDeckMode', 'false'), prop('boolean', 'ClassDeckMode', 'false'),
prop('boolean', 'DebugCardPickerMode', 'false'),
prop('boolean', 'DebugCtrlDown', 'false'),
prop('boolean', 'DebugShiftDown', 'false'),
prop('any', 'ClassDeckCards'), prop('any', 'ClassDeckCards'),
prop('string', 'ClassDeckTitle', '""'), prop('string', 'ClassDeckTitle', '""'),
prop('string', 'ClassDeckClass', '""'), prop('string', 'ClassDeckClass', '""'),

View File

@@ -116,11 +116,12 @@ export function buildDeckAll() {
path: cardPath, path: cardPath,
modelId: 'uisprite', modelId: 'uisprite',
entryId: 'UISprite', entryId: 'UISprite',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent', componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent',
displayOrder: i, displayOrder: i,
components: [ components: [
transform({ parentW: 980, parentH: 620, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: ALL_DECK_CARD_W, y: ALL_DECK_CARD_H }, pos: { x: 0, y: 0 } }), transform({ parentW: 980, parentH: 620, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: ALL_DECK_CARD_W, y: ALL_DECK_CARD_H }, pos: { x: 0, y: 0 } }),
sprite({ dataId: CARDFRAMES.frames.warrior.normal, color: WHITE, type: 0 }), sprite({ dataId: CARDFRAMES.frames.warrior.normal, color: WHITE, type: 0, raycast: true }),
button(),
], ],
}); });
card.jsonString.enable = false; card.jsonString.enable = false;