메이플 전사 전직 스킬 카드 및 연계 기믹 구현 #110
File diff suppressed because one or more lines are too long
157
data/cards.json
157
data/cards.json
@@ -45,7 +45,7 @@
|
||||
"fx": "48754be05be344358cddd55aa8fe11f4"
|
||||
},
|
||||
"MoltenFist": {
|
||||
"name": "녹아내리는 주먹",
|
||||
"name": "불꽃 강타",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 10,
|
||||
@@ -58,7 +58,7 @@
|
||||
"fx": "6f283d96d5804b4fb88009685a11c1f8"
|
||||
},
|
||||
"BodySlam": {
|
||||
"name": "몸통 박치기",
|
||||
"name": "방패 밀어치기",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damageFromCurrentBlock": 1,
|
||||
@@ -81,7 +81,7 @@
|
||||
"fx": "2799562e984c4a4da3b73e1f3431057c"
|
||||
},
|
||||
"SwordBoomerang": {
|
||||
"name": "부메랑 칼날",
|
||||
"name": "회전 검격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 3,
|
||||
@@ -94,7 +94,7 @@
|
||||
"fx": "1b0afc410a1a458598eb7ca2fb26e97d"
|
||||
},
|
||||
"SetupStrike": {
|
||||
"name": "사전 타격",
|
||||
"name": "기선 타격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 7,
|
||||
@@ -106,7 +106,7 @@
|
||||
"fx": "291b2298db88476f8ae3c6c78f53c9b7"
|
||||
},
|
||||
"TwinStrike": {
|
||||
"name": "이중 타격",
|
||||
"name": "연속 타격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 5,
|
||||
@@ -118,7 +118,7 @@
|
||||
"fx": "863812c5c2f84132ac7465b50ec2283e"
|
||||
},
|
||||
"Breakthrough": {
|
||||
"name": "정면 돌파",
|
||||
"name": "전선 돌파",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 9,
|
||||
@@ -130,7 +130,7 @@
|
||||
"fx": "e8a145a6c43d493f9ad50fab03b200aa"
|
||||
},
|
||||
"Thunderclap": {
|
||||
"name": "천둥",
|
||||
"name": "전장의 벼락",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 4,
|
||||
@@ -144,7 +144,7 @@
|
||||
"fx": "48754be05be344358cddd55aa8fe11f4"
|
||||
},
|
||||
"IronWave": {
|
||||
"name": "철의 파동",
|
||||
"name": "강철 검기",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 5,
|
||||
@@ -156,7 +156,7 @@
|
||||
"fx": "6f283d96d5804b4fb88009685a11c1f8"
|
||||
},
|
||||
"PommelStrike": {
|
||||
"name": "폼멜 타격",
|
||||
"name": "칼자루 타격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 9,
|
||||
@@ -168,7 +168,7 @@
|
||||
"fx": "997fa6999aa04dbb97a1dd99025fa2ba"
|
||||
},
|
||||
"PerfectedStrike": {
|
||||
"name": "완벽한 타격",
|
||||
"name": "숙련된 타격",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 6,
|
||||
@@ -181,7 +181,7 @@
|
||||
"fx": "2799562e984c4a4da3b73e1f3431057c"
|
||||
},
|
||||
"Cinder": {
|
||||
"name": "잿불",
|
||||
"name": "잿불 검격",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 18,
|
||||
@@ -193,7 +193,7 @@
|
||||
"fx": "1b0afc410a1a458598eb7ca2fb26e97d"
|
||||
},
|
||||
"Bloodletting": {
|
||||
"name": "사혈",
|
||||
"name": "투지 분출",
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"gainEnergy": 2,
|
||||
@@ -203,7 +203,7 @@
|
||||
"rarity": "normal"
|
||||
},
|
||||
"Tremble": {
|
||||
"name": "떨림",
|
||||
"name": "위압",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"vuln": 3,
|
||||
@@ -225,7 +225,7 @@
|
||||
"rarity": "normal"
|
||||
},
|
||||
"TrueGrit": {
|
||||
"name": "진정한 끈기",
|
||||
"name": "강철 의지",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"block": 7,
|
||||
@@ -236,7 +236,7 @@
|
||||
"rarity": "normal"
|
||||
},
|
||||
"Havoc": {
|
||||
"name": "파괴",
|
||||
"name": "전투 전술",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"nextSkillCostZero": true,
|
||||
@@ -246,7 +246,7 @@
|
||||
"rarity": "normal"
|
||||
},
|
||||
"ShrugItOff": {
|
||||
"name": "흘려보내기",
|
||||
"name": "충격 흘리기",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"block": 8,
|
||||
@@ -257,7 +257,7 @@
|
||||
"rarity": "normal"
|
||||
},
|
||||
"BloodWall": {
|
||||
"name": "피의 벽",
|
||||
"name": "붉은 방벽",
|
||||
"cost": 2,
|
||||
"kind": "Skill",
|
||||
"block": 16,
|
||||
@@ -281,7 +281,7 @@
|
||||
"fx": "1b0afc410a1a458598eb7ca2fb26e97d"
|
||||
},
|
||||
"Spite": {
|
||||
"name": "악의",
|
||||
"name": "맹공",
|
||||
"cost": 0,
|
||||
"kind": "Attack",
|
||||
"damage": 5,
|
||||
@@ -293,7 +293,7 @@
|
||||
"fx": "291b2298db88476f8ae3c6c78f53c9b7"
|
||||
},
|
||||
"Bully": {
|
||||
"name": "협박",
|
||||
"name": "전장의 압박",
|
||||
"cost": 0,
|
||||
"kind": "Attack",
|
||||
"damage": 4,
|
||||
@@ -305,7 +305,7 @@
|
||||
"fx": "863812c5c2f84132ac7465b50ec2283e"
|
||||
},
|
||||
"Pillage": {
|
||||
"name": "갈취",
|
||||
"name": "전리품 확보",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 6,
|
||||
@@ -317,7 +317,7 @@
|
||||
"fx": "e8a145a6c43d493f9ad50fab03b200aa"
|
||||
},
|
||||
"Rampage": {
|
||||
"name": "광란",
|
||||
"name": "거듭된 맹공",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 12,
|
||||
@@ -329,7 +329,7 @@
|
||||
"fx": "48754be05be344358cddd55aa8fe11f4"
|
||||
},
|
||||
"AshenStrike": {
|
||||
"name": "잿빛 타격",
|
||||
"name": "누적 타격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 6,
|
||||
@@ -341,7 +341,7 @@
|
||||
"fx": "6f283d96d5804b4fb88009685a11c1f8"
|
||||
},
|
||||
"Dismantle": {
|
||||
"name": "해체",
|
||||
"name": "갑주 가르기",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 8,
|
||||
@@ -353,7 +353,7 @@
|
||||
"fx": "997fa6999aa04dbb97a1dd99025fa2ba"
|
||||
},
|
||||
"Hemokinesis": {
|
||||
"name": "혈류",
|
||||
"name": "혼신의 일격",
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 15,
|
||||
@@ -364,7 +364,7 @@
|
||||
"fx": "2799562e984c4a4da3b73e1f3431057c"
|
||||
},
|
||||
"FightMe": {
|
||||
"name": "덤벼라!",
|
||||
"name": "결투 신청",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 5,
|
||||
@@ -377,7 +377,7 @@
|
||||
"fx": "1b0afc410a1a458598eb7ca2fb26e97d"
|
||||
},
|
||||
"Unrelenting": {
|
||||
"name": "무자비",
|
||||
"name": "진격의 일격",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 14,
|
||||
@@ -402,7 +402,7 @@
|
||||
"fx": "863812c5c2f84132ac7465b50ec2283e"
|
||||
},
|
||||
"Bludgeon": {
|
||||
"name": "몽둥이질",
|
||||
"name": "대검 강타",
|
||||
"cost": 3,
|
||||
"kind": "Attack",
|
||||
"damage": 32,
|
||||
@@ -413,7 +413,7 @@
|
||||
"fx": "e8a145a6c43d493f9ad50fab03b200aa"
|
||||
},
|
||||
"HowlFromBeyond": {
|
||||
"name": "저편의 울음소리",
|
||||
"name": "전장의 포효",
|
||||
"cost": 3,
|
||||
"kind": "Attack",
|
||||
"damage": 16,
|
||||
@@ -426,7 +426,7 @@
|
||||
"fx": "48754be05be344358cddd55aa8fe11f4"
|
||||
},
|
||||
"Stomp": {
|
||||
"name": "짓밟기",
|
||||
"name": "진형 붕괴",
|
||||
"cost": 3,
|
||||
"kind": "Attack",
|
||||
"damage": 12,
|
||||
@@ -450,7 +450,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"BattleTrance": {
|
||||
"name": "전투 최면",
|
||||
"name": "전투 집중",
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"draw": 3,
|
||||
@@ -461,7 +461,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"Colossus": {
|
||||
"name": "거상",
|
||||
"name": "철벽 자세",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"block": 5,
|
||||
@@ -494,7 +494,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"BurningPact": {
|
||||
"name": "불타는 조약",
|
||||
"name": "결사의 각오",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"discard": 1,
|
||||
@@ -505,7 +505,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"EvilEye": {
|
||||
"name": "악마의 눈",
|
||||
"name": "빈틈없는 방어",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"block": 16,
|
||||
@@ -515,7 +515,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"ForgottenRitual": {
|
||||
"name": "잊힌 의식",
|
||||
"name": "비상 전력",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"gainEnergy": 2,
|
||||
@@ -550,7 +550,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"InfernalBlade": {
|
||||
"name": "지옥검",
|
||||
"name": "임시 무장",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"addRandomCardCount": 1,
|
||||
@@ -585,7 +585,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"StoneArmor": {
|
||||
"name": "돌 갑옷",
|
||||
"name": "강철 갑옷",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"powerEffect": "blockPerTurn",
|
||||
@@ -596,7 +596,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"FeelNoPain": {
|
||||
"name": "무감각",
|
||||
"name": "고통 인내",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"powerEffect": "blockPerTurn",
|
||||
@@ -629,7 +629,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"Juggling": {
|
||||
"name": "저글링",
|
||||
"name": "연속 공세",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"cardPlayedRandomDamage": 3,
|
||||
@@ -670,7 +670,7 @@
|
||||
"rarity": "unique"
|
||||
},
|
||||
"PactsEnd": {
|
||||
"name": "조약의 끝",
|
||||
"name": "최후의 일격",
|
||||
"cost": 0,
|
||||
"kind": "Attack",
|
||||
"damage": 17,
|
||||
@@ -722,7 +722,7 @@
|
||||
"fx": "997fa6999aa04dbb97a1dd99025fa2ba"
|
||||
},
|
||||
"TearAsunder": {
|
||||
"name": "갈가리 찢기",
|
||||
"name": "삼연참",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 5,
|
||||
@@ -734,7 +734,7 @@
|
||||
"fx": "2799562e984c4a4da3b73e1f3431057c"
|
||||
},
|
||||
"FiendFire": {
|
||||
"name": "지옥불",
|
||||
"name": "최후의 패",
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 0,
|
||||
@@ -748,7 +748,7 @@
|
||||
"fx": "1b0afc410a1a458598eb7ca2fb26e97d"
|
||||
},
|
||||
"Mangle": {
|
||||
"name": "난도질",
|
||||
"name": "공포의 일격",
|
||||
"cost": 3,
|
||||
"kind": "Attack",
|
||||
"damage": 15,
|
||||
@@ -771,7 +771,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Cascade": {
|
||||
"name": "연쇄",
|
||||
"name": "연속 전개",
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"useAllEnergy": true,
|
||||
@@ -783,7 +783,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"PrimalForce": {
|
||||
"name": "원시의 힘",
|
||||
"name": "전사의 본능",
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"handCostZeroThisTurn": true,
|
||||
@@ -793,7 +793,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Offering": {
|
||||
"name": "제물",
|
||||
"name": "전력 방출",
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"gainEnergy": 2,
|
||||
@@ -805,7 +805,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"OneTwoPunch": {
|
||||
"name": "원투 펀치",
|
||||
"name": "연계 전술",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"nextSkillRepeatCount": 1,
|
||||
@@ -815,7 +815,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Stoke": {
|
||||
"name": "화력 증폭",
|
||||
"name": "전투 재정비",
|
||||
"cost": 1,
|
||||
"kind": "Skill",
|
||||
"exhaustHandAll": true,
|
||||
@@ -849,7 +849,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Aggression": {
|
||||
"name": "공격성",
|
||||
"name": "공격 태세",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"turnStartDraw": 1,
|
||||
@@ -859,7 +859,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Cruelty": {
|
||||
"name": "악랄함",
|
||||
"name": "전투 광기",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"powerEffect": "strengthPerTurn",
|
||||
@@ -870,7 +870,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"CrimsonMantle": {
|
||||
"name": "핏빛 망토",
|
||||
"name": "붉은 수호",
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"powerEffect": "blockPerTurn",
|
||||
@@ -892,7 +892,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"DarkEmbrace": {
|
||||
"name": "어둠의 포옹",
|
||||
"name": "소멸의 숙련",
|
||||
"cost": 2,
|
||||
"kind": "Power",
|
||||
"drawOnExhaust": 1,
|
||||
@@ -914,7 +914,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Juggernaut": {
|
||||
"name": "절대적인 힘",
|
||||
"name": "검격 파동",
|
||||
"cost": 2,
|
||||
"kind": "Power",
|
||||
"cardPlayedRandomDamage": 5,
|
||||
@@ -924,7 +924,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"Hellraiser": {
|
||||
"name": "지옥검무",
|
||||
"name": "타격의 달인",
|
||||
"cost": 2,
|
||||
"kind": "Power",
|
||||
"drawNameMatchAutoPlay": "타격",
|
||||
@@ -945,7 +945,7 @@
|
||||
"rarity": "legend"
|
||||
},
|
||||
"DemonForm": {
|
||||
"name": "악마의 형상",
|
||||
"name": "전신 투지",
|
||||
"cost": 3,
|
||||
"kind": "Power",
|
||||
"powerEffect": "strengthPerTurn",
|
||||
@@ -1045,11 +1045,12 @@
|
||||
},
|
||||
"ComboAttack": {
|
||||
"name": "콤보 어택",
|
||||
"cost": 1,
|
||||
"cost": 0,
|
||||
"kind": "Power",
|
||||
"comboOnAttack": 1,
|
||||
"comboMax": 5,
|
||||
"desc": "공격 카드를 사용할 때마다 콤보 1 획득. 최대 5",
|
||||
"attackDamagePerCombo": 0.5,
|
||||
"desc": "공격마다 콤보 1 획득. 모든 공격이 콤보 2당 피해 +1. 최대 5",
|
||||
"image": "e2580523efc6457385114b78ad0d7cce",
|
||||
"class": "fighter",
|
||||
"rarity": "unique"
|
||||
@@ -1099,7 +1100,7 @@
|
||||
},
|
||||
"FighterPhysicalTraining": {
|
||||
"name": "피지컬 트레이닝",
|
||||
"cost": 2,
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"strength": 1,
|
||||
"dex": 1,
|
||||
@@ -1139,7 +1140,7 @@
|
||||
},
|
||||
"Rush": {
|
||||
"name": "돌진",
|
||||
"cost": 1,
|
||||
"cost": 2,
|
||||
"kind": "Attack",
|
||||
"damage": 8,
|
||||
"aoe": true,
|
||||
@@ -1162,12 +1163,13 @@
|
||||
},
|
||||
"ComboSynergy": {
|
||||
"name": "콤보 시너지",
|
||||
"cost": 2,
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"comboOnAttack": 1,
|
||||
"comboMax": 5,
|
||||
"attackDamagePerCombo": 1,
|
||||
"desc": "공격마다 콤보 1 획득. 모든 공격이 콤보당 피해 +1. 최대 5",
|
||||
"comboGain": 2,
|
||||
"attackDamagePerCombo": 0.5,
|
||||
"desc": "콤보 2 획득. 공격마다 콤보 1 획득. 모든 공격이 콤보 2당 피해 +1. 최대 5",
|
||||
"image": "e2580523efc6457385114b78ad0d7cce",
|
||||
"class": "crusader",
|
||||
"rarity": "legend"
|
||||
@@ -1188,7 +1190,8 @@
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"attackDamageVsWeakMultiplier": 1.5,
|
||||
"desc": "약화 상태인 적에게 주는 공격 피해 1.5배",
|
||||
"comboGain": 2,
|
||||
"desc": "콤보 2 획득. 약화 상태인 적에게 주는 공격 피해 1.5배",
|
||||
"image": "291b2298db88476f8ae3c6c78f53c9b7",
|
||||
"class": "crusader",
|
||||
"rarity": "unique"
|
||||
@@ -1263,8 +1266,8 @@
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"powerEffect": "blockPerTurn",
|
||||
"value": 4,
|
||||
"desc": "매턴 방어도 4",
|
||||
"value": 3,
|
||||
"desc": "매턴 방어도 3",
|
||||
"image": "90a9bf8eeb844b578b4e2d93ac43fedf",
|
||||
"class": "page",
|
||||
"rarity": "normal"
|
||||
@@ -1304,28 +1307,28 @@
|
||||
},
|
||||
"DivineCharge": {
|
||||
"name": "디바인 차지",
|
||||
"cost": 2,
|
||||
"cost": 1,
|
||||
"kind": "Attack",
|
||||
"damage": 4,
|
||||
"damage": 3,
|
||||
"hits": 4,
|
||||
"aoe": true,
|
||||
"weak": 1,
|
||||
"affectsAllEnemies": true,
|
||||
"holyForce": true,
|
||||
"damagePerHolyCharge": 1,
|
||||
"desc": "모든 적에게 피해 4 x 4회, 약화 1. 홀리 차지당 피해 +1. 홀리 포스.",
|
||||
"desc": "모든 적에게 피해 3 x 4회, 약화 1. 홀리 차지당 피해 +1. 홀리 포스.",
|
||||
"image": "863812c5c2f84132ac7465b50ec2283e",
|
||||
"class": "knight",
|
||||
"rarity": "unique"
|
||||
},
|
||||
"Restoration": {
|
||||
"name": "리스토네이션",
|
||||
"cost": 1,
|
||||
"cost": 0,
|
||||
"kind": "Skill",
|
||||
"heal": 8,
|
||||
"heal": 6,
|
||||
"healPerHolyCharge": 4,
|
||||
"holyChargeSpendAll": true,
|
||||
"desc": "HP 8 회복. 홀리 차지당 추가로 4 회복한 뒤 모두 소비",
|
||||
"desc": "HP 6 회복. 홀리 차지당 추가로 4 회복한 뒤 모두 소비",
|
||||
"image": "90a9bf8eeb844b578b4e2d93ac43fedf",
|
||||
"class": "knight",
|
||||
"rarity": "unique"
|
||||
@@ -1358,7 +1361,7 @@
|
||||
},
|
||||
"ParashockGuard": {
|
||||
"name": "파라쇼크 가드",
|
||||
"cost": 2,
|
||||
"cost": 3,
|
||||
"kind": "Power",
|
||||
"strength": 1,
|
||||
"thorns": 3,
|
||||
@@ -1370,7 +1373,7 @@
|
||||
},
|
||||
"CombatOrders": {
|
||||
"name": "컴뱃 오더스",
|
||||
"cost": 2,
|
||||
"cost": 1,
|
||||
"kind": "Power",
|
||||
"nextSkillRepeatCount": 1,
|
||||
"turnStartDraw": 1,
|
||||
@@ -1384,9 +1387,9 @@
|
||||
"cost": 2,
|
||||
"kind": "Power",
|
||||
"powerEffect": "blockPerTurn",
|
||||
"value": 5,
|
||||
"thorns": 2,
|
||||
"desc": "매턴 방어도 5. 가시 2",
|
||||
"value": 4,
|
||||
"thorns": 1,
|
||||
"desc": "매턴 방어도 4. 가시 1",
|
||||
"image": "90a9bf8eeb844b578b4e2d93ac43fedf",
|
||||
"class": "knight",
|
||||
"rarity": "unique"
|
||||
@@ -2999,11 +3002,11 @@
|
||||
"Strike",
|
||||
"Strike",
|
||||
"Strike",
|
||||
"Strike",
|
||||
"Defend",
|
||||
"SlashBlast",
|
||||
"Defend",
|
||||
"Defend",
|
||||
"Defend",
|
||||
"IronBody",
|
||||
"Bash"
|
||||
],
|
||||
"magician": [
|
||||
|
||||
BIN
data/cards.xlsx
BIN
data/cards.xlsx
Binary file not shown.
@@ -6,7 +6,10 @@ import {
|
||||
simulateCombat,
|
||||
} from './sim-balance.mjs';
|
||||
|
||||
const ROGUE_CLASSES = new Set(['rogue', 'thief', 'thiefmaster', 'assassin', 'hermit']);
|
||||
const AUDITED_CLASSES = new Set([
|
||||
'rogue', 'thief', 'thiefmaster', 'assassin', 'hermit',
|
||||
'warrior', 'fighter', 'crusader', 'page', 'knight',
|
||||
]);
|
||||
|
||||
const CONTEXT_DECKS = {
|
||||
rogue: [
|
||||
@@ -38,6 +41,27 @@ const CONTEXT_DECKS = {
|
||||
'Survivor', 'LeadingStrike', 'BladeDance', 'JavelinAcceleration',
|
||||
'JavelinMastery', 'TripleThrow', 'SpiritJavelin', 'SkilledJavelin',
|
||||
],
|
||||
warrior: [
|
||||
'Strike', 'Strike', 'Strike', 'Strike',
|
||||
'Defend', 'Defend', 'Defend', 'Defend',
|
||||
'Bash', 'SlashBlast', 'IronBody', 'WarriorMastery',
|
||||
],
|
||||
fighter: [
|
||||
'Strike', 'Strike', 'Strike', 'Defend', 'Defend', 'Defend',
|
||||
'Bash', 'SlashBlast', 'ComboAttack', 'Brandish', 'WeaponMastery', 'FlashSlash',
|
||||
],
|
||||
crusader: [
|
||||
'Strike', 'Strike', 'Defend', 'Defend', 'Bash', 'SlashBlast',
|
||||
'ComboAttack', 'Brandish', 'WeaponMastery', 'BraveSlash', 'ComboSynergy', 'Rush',
|
||||
],
|
||||
page: [
|
||||
'Strike', 'Strike', 'Strike', 'Defend', 'Defend', 'Defend',
|
||||
'Bash', 'SlashBlast', 'HolyCharge', 'DivineSwing', 'PageOrder', 'PageStance',
|
||||
],
|
||||
knight: [
|
||||
'Strike', 'Strike', 'Defend', 'Defend', 'Bash', 'SlashBlast',
|
||||
'HolyCharge', 'DivineSwing', 'PageOrder', 'DivineCharge', 'KnightRush', 'Restoration',
|
||||
],
|
||||
};
|
||||
|
||||
const ENCOUNTER_SCALE = {
|
||||
@@ -46,6 +70,11 @@ const ENCOUNTER_SCALE = {
|
||||
assassin: { hp: 2.25, attack: 1.65 },
|
||||
thiefmaster: { hp: 2.4, attack: 1.5 },
|
||||
hermit: { hp: 2.6, attack: 1.65 },
|
||||
warrior: { hp: 1.9, attack: 1.5 },
|
||||
fighter: { hp: 2.2, attack: 1.6 },
|
||||
crusader: { hp: 2.6, attack: 1.7 },
|
||||
page: { hp: 2.2, attack: 1.6 },
|
||||
knight: { hp: 2.6, attack: 1.7 },
|
||||
};
|
||||
|
||||
const median = (values) => {
|
||||
@@ -172,7 +201,7 @@ export function auditCardEfficiency({ runs = 300, seed = 20260701 } = {}) {
|
||||
|
||||
const rows = [];
|
||||
for (const [id, card] of Object.entries(cards)) {
|
||||
if (!ROGUE_CLASSES.has(card.class)) continue;
|
||||
if (!AUDITED_CLASSES.has(card.class)) continue;
|
||||
const deck = CONTEXT_DECKS[card.class].slice();
|
||||
deck[replacementIndex(deck, cards, card)] = id;
|
||||
const result = simulateDeck(scaledEncounter(data, card.class), deck, runs, seed, id);
|
||||
@@ -204,7 +233,7 @@ function formatPercent(value) {
|
||||
|
||||
export function formatEfficiencyReport(report) {
|
||||
const lines = [];
|
||||
lines.push(`도적 카드 효율 검증: 카드 ${report.rows.length}장, 카드당 ${report.runs}회`);
|
||||
lines.push(`카드 효율 검증: 카드 ${report.rows.length}장, 카드당 ${report.runs}회`);
|
||||
lines.push('기준 덱:');
|
||||
for (const [classId, baseline] of Object.entries(report.baselines)) {
|
||||
lines.push(` ${classId}: 승률 ${formatPercent(baseline.winRate)}, 평균 ${baseline.avgTurns.toFixed(2)}턴, 승리 HP ${baseline.avgHpOnWin.toFixed(1)}`);
|
||||
|
||||
@@ -6,7 +6,7 @@ const cardsData = JSON.parse(readFileSync('data/cards.json', 'utf8'));
|
||||
const enemiesData = JSON.parse(readFileSync('data/enemies.json', 'utf8'));
|
||||
const relicsData = JSON.parse(readFileSync('data/relics.json', 'utf8'));
|
||||
|
||||
const PLAYER_MAX_HP = 70;
|
||||
const PLAYER_MAX_HP = { rogue: 70, warrior: 80 };
|
||||
const REST_HEAL = 30;
|
||||
const SECTION_COUNT = 5;
|
||||
const NORMAL_FIGHTS = 4;
|
||||
@@ -18,6 +18,8 @@ const BOSS_POOL = ['king_slime', 'slime_boss'];
|
||||
const JOBS = {
|
||||
thief: { tier2: 'thief', tier3: 'thiefmaster', tier2Starter: 'DaggerAcceleration', tier3Starter: 'Venom' },
|
||||
assassin: { tier2: 'assassin', tier3: 'hermit', tier2Starter: 'JavelinAcceleration', tier3Starter: 'SpiritJavelin' },
|
||||
fighter: { root: 'warrior', tier2: 'fighter', tier3: 'crusader', tier2Starter: 'ComboAttack', tier3Starter: 'ComboSynergy' },
|
||||
page: { root: 'warrior', tier2: 'page', tier3: 'knight', tier2Starter: 'HolyCharge', tier3Starter: 'DivineCharge' },
|
||||
};
|
||||
|
||||
const LINEAGES = {
|
||||
@@ -26,12 +28,17 @@ const LINEAGES = {
|
||||
thiefmaster: ['rogue', 'thief', 'thiefmaster'],
|
||||
assassin: ['rogue', 'assassin'],
|
||||
hermit: ['rogue', 'assassin', 'hermit'],
|
||||
warrior: ['warrior'],
|
||||
fighter: ['warrior', 'fighter'],
|
||||
crusader: ['warrior', 'fighter', 'crusader'],
|
||||
page: ['warrior', 'page'],
|
||||
knight: ['warrior', 'page', 'knight'],
|
||||
};
|
||||
|
||||
const pick = (rng, values) => values[Math.floor(rng() * values.length)];
|
||||
|
||||
export function campaignJobAtSection(branch, section) {
|
||||
if (section <= 1) return 'rogue';
|
||||
if (section <= 1) return JOBS[branch].root || 'rogue';
|
||||
if (section === 2) return JOBS[branch].tier2;
|
||||
return JOBS[branch].tier3;
|
||||
}
|
||||
@@ -102,11 +109,22 @@ function branchCardValue(card, branch, deck, id) {
|
||||
value += card.sly ? 5 : 0;
|
||||
value += (card.discard || 0) * 2 + (card.drawPerDiscarded || 0) * 4;
|
||||
value += (card.poisonApplicationBurstDamage || 0) * 1.5;
|
||||
} else {
|
||||
} else if (branch === 'assassin') {
|
||||
value += (card.addShiv || 0) * 3 + (card.turnStartShiv || 0) * 8;
|
||||
value += (card.shivDamageBonus || 0) * 6 + (card.firstShivDamageBonus || 0) * 3;
|
||||
value += card.shivAoe ? 12 : 0;
|
||||
value += card.shivRetain ? 5 : 0;
|
||||
} else if (branch === 'fighter') {
|
||||
value += (card.hits || 1) * 1.5;
|
||||
value += (card.comboGain || 0) * 5 + (card.comboOnAttack || 0) * 10;
|
||||
value += (card.damagePerCombo || 0) * 8 + (card.attackDamagePerCombo || 0) * 12;
|
||||
value += (card.attackPlayedDamage || 0) * 5;
|
||||
} else if (branch === 'page') {
|
||||
value += (card.block || 0) * 0.5 + (card.cardPlayedBlock || 0) * 7;
|
||||
value += (card.holyChargeOnHolyForce || 0) * 12 + (card.damagePerHolyCharge || 0) * 7;
|
||||
value += (card.blockPerHolyCharge || 0) * 6 + (card.healPerHolyCharge || 0) * 3;
|
||||
value += (card.damageTakenReduction || 0) * 40;
|
||||
value += (card.blockOnDamaged || 0) * 3 + (card.strengthOnDamagedOnce || 0) * 5;
|
||||
}
|
||||
const copies = deck.filter((cardId) => cardId === id).length;
|
||||
value -= copies * (card.kind === 'Power' ? 10 : 3);
|
||||
@@ -203,11 +221,13 @@ export function simulateCampaign(branch, rng, {
|
||||
minimumRewardValue = 10,
|
||||
} = {}) {
|
||||
if (!JOBS[branch]) throw new Error(`지원하지 않는 도적 분기: ${branch}`);
|
||||
const root = JOBS[branch].root || 'rogue';
|
||||
const maxHp = PLAYER_MAX_HP[root];
|
||||
const state = {
|
||||
hp: PLAYER_MAX_HP,
|
||||
maxHp: PLAYER_MAX_HP,
|
||||
deck: cardsData.starterDecks.rogue.slice(),
|
||||
job: 'rogue',
|
||||
hp: maxHp,
|
||||
maxHp,
|
||||
deck: cardsData.starterDecks[root].slice(),
|
||||
job: root,
|
||||
turns: 0,
|
||||
sectionCleared: 0,
|
||||
diedAt: '',
|
||||
@@ -306,7 +326,7 @@ function main() {
|
||||
else if (args[i] === '--scale-step') scaleStep = Number.parseFloat(args[++i]);
|
||||
else if (args[i] === '--reward-min') minimumRewardValue = Number.parseFloat(args[++i]);
|
||||
}
|
||||
for (const branch of ['thief', 'assassin']) {
|
||||
for (const branch of ['thief', 'assassin', 'fighter', 'page']) {
|
||||
console.log(formatCampaignReport(runCampaignBatch(branch, runs, seed, { restHeal, sectionHeal, scaleStep, minimumRewardValue })));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,16 @@ test('도적 전직 시점: 1섹션 Rogue, 2섹션 2차, 3섹션부터 3차', ()
|
||||
test('3차 직업은 자기 계보 카드만 사용', () => {
|
||||
assert.deepEqual(playableClassesForJob('thiefmaster'), ['rogue', 'thief', 'thiefmaster']);
|
||||
assert.deepEqual(playableClassesForJob('hermit'), ['rogue', 'assassin', 'hermit']);
|
||||
assert.deepEqual(playableClassesForJob('crusader'), ['warrior', 'fighter', 'crusader']);
|
||||
assert.deepEqual(playableClassesForJob('knight'), ['warrior', 'page', 'knight']);
|
||||
});
|
||||
|
||||
test('전사 전직 시점: 1섹션 Warrior, 2섹션 2차, 3섹션부터 3차', () => {
|
||||
assert.equal(campaignJobAtSection('fighter', 1), 'warrior');
|
||||
assert.equal(campaignJobAtSection('fighter', 2), 'fighter');
|
||||
assert.equal(campaignJobAtSection('fighter', 3), 'crusader');
|
||||
assert.equal(campaignJobAtSection('page', 2), 'page');
|
||||
assert.equal(campaignJobAtSection('page', 5), 'knight');
|
||||
});
|
||||
|
||||
test('섹션 난이도는 3차 이후 더 빠르게 증가', () => {
|
||||
|
||||
Reference in New Issue
Block a user