From 926733dbefb04d1b4bee7afda221f62ab4bc853f Mon Sep 17 00:00:00 2001 From: gahusb Date: Mon, 29 Jun 2026 18:21:08 +0900 Subject: [PATCH] =?UTF-8?q?fix(deck):=20firstCardDamageBonus=20=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20class=E2=86=92kind=20(=EC=98=81=EA=B5=AC?= =?UTF-8?q?=20=EB=AF=B8=EB=B0=9C=EB=8F=99=20=EB=B2=84=EA=B7=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChargedBlow(class=warrior, kind=Attack, firstCardDamageBonus=2)의 첫-카드 보너스가 Lua·JS 양쪽에서 `c.class == "Attack"`로 게이트돼 있었다. class는 warrior/bandit 등이라 절대 "Attack"이 아니어서 보너스가 영구 미발동(죽은 코드). kind가 "Attack"이므로 `c.kind == "Attack"`로 수정(양쪽 미러). RED-GREEN 회귀 테스트 추가: class=warrior·kind=Attack 카드의 첫 카드 보너스로 7뎀 → 1턴 처치(미수정 시 5뎀 2턴). 테스트 84→85. 산출물 재생성 포함. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01UUvHKjrt8jqLzDeCsRRGmj --- RootDesk/MyDesk/SlayDeckController.codeblock | 2 +- tools/balance/sim-balance.mjs | 2 +- tools/balance/sim-balance.test.mjs | 13 +++++++++++++ tools/deck/cb/hand.mjs | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/RootDesk/MyDesk/SlayDeckController.codeblock b/RootDesk/MyDesk/SlayDeckController.codeblock index 315ddde..130a2b1 100644 --- a/RootDesk/MyDesk/SlayDeckController.codeblock +++ b/RootDesk/MyDesk/SlayDeckController.codeblock @@ -2886,7 +2886,7 @@ "Name": "c" } ], - "Code": "local base2 = c.damage or 0\nlocal otherHand = 0\nif self.Hand ~= nil then\n\totherHand = #self.Hand - 1\n\tif otherHand < 0 then otherHand = 0 end\nend\nif c.damagePerOtherHandCard ~= nil then\n\tbase2 = base2 + otherHand * c.damagePerOtherHandCard\nend\nif c.damagePerAttackPlayedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnAttackCardsPlayed or 0) * c.damagePerAttackPlayedThisTurn\nend\nif c.damagePerDiscardedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnDiscardedCards or 0) * c.damagePerDiscardedThisTurn\nend\nif c.damagePerSkillInHand ~= nil then\n\tbase2 = base2 + self:CountOtherHandSkills(slot) * c.damagePerSkillInHand\nend\nif c.damagePerCardDrawnThisCombat ~= nil then\n\tbase2 = base2 + (self.CardsDrawnThisCombat or 0) * c.damagePerCardDrawnThisCombat\nend\nif c.class == \"Attack\" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then\n\tbase2 = base2 + c.firstCardDamageBonus\nend\nif c.class == \"shiv\" then\n\tif self:HasPowerField(\"shivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"shivDamageBonus\")\n\tend\n\tif self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField(\"firstShivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"firstShivDamageBonus\")\n\tend\nend\nif base2 < 0 then\n\tbase2 = 0\nend\nreturn base2", + "Code": "local base2 = c.damage or 0\nlocal otherHand = 0\nif self.Hand ~= nil then\n\totherHand = #self.Hand - 1\n\tif otherHand < 0 then otherHand = 0 end\nend\nif c.damagePerOtherHandCard ~= nil then\n\tbase2 = base2 + otherHand * c.damagePerOtherHandCard\nend\nif c.damagePerAttackPlayedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnAttackCardsPlayed or 0) * c.damagePerAttackPlayedThisTurn\nend\nif c.damagePerDiscardedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnDiscardedCards or 0) * c.damagePerDiscardedThisTurn\nend\nif c.damagePerSkillInHand ~= nil then\n\tbase2 = base2 + self:CountOtherHandSkills(slot) * c.damagePerSkillInHand\nend\nif c.damagePerCardDrawnThisCombat ~= nil then\n\tbase2 = base2 + (self.CardsDrawnThisCombat or 0) * c.damagePerCardDrawnThisCombat\nend\nif c.kind == \"Attack\" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then\n\tbase2 = base2 + c.firstCardDamageBonus\nend\nif c.class == \"shiv\" then\n\tif self:HasPowerField(\"shivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"shivDamageBonus\")\n\tend\n\tif self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField(\"firstShivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"firstShivDamageBonus\")\n\tend\nend\nif base2 < 0 then\n\tbase2 = 0\nend\nreturn base2", "Scope": 2, "ExecSpace": 6, "Attributes": [], diff --git a/tools/balance/sim-balance.mjs b/tools/balance/sim-balance.mjs index 9f3988f..3cd2b2b 100644 --- a/tools/balance/sim-balance.mjs +++ b/tools/balance/sim-balance.mjs @@ -342,7 +342,7 @@ export function simulateCombat(data, rng, stats) { if (c.damagePerDiscardedThisTurn) base += turnDiscardedCards * c.damagePerDiscardedThisTurn; if (c.damagePerSkillInHand) base += countOtherHandSkills(id) * c.damagePerSkillInHand; if (c.damagePerCardDrawnThisCombat) base += cardsDrawnThisCombat * c.damagePerCardDrawnThisCombat; - if (c.class === 'Attack' && turnCardsPlayedThisTurn === 0 && c.firstCardDamageBonus) base += c.firstCardDamageBonus; + if (c.kind === 'Attack' && turnCardsPlayedThisTurn === 0 && c.firstCardDamageBonus) base += c.firstCardDamageBonus; if (c.class === 'shiv') { if (powerFieldTotal('shivDamageBonus') > 0) base += powerFieldTotal('shivDamageBonus'); if (!shivFirstDamageBonusUsed && powerFieldTotal('firstShivDamageBonus') > 0) base += powerFieldTotal('firstShivDamageBonus'); diff --git a/tools/balance/sim-balance.test.mjs b/tools/balance/sim-balance.test.mjs index 071ee0b..dabeab9 100644 --- a/tools/balance/sim-balance.test.mjs +++ b/tools/balance/sim-balance.test.mjs @@ -262,6 +262,19 @@ test('simulateCombat: 카드 취약 부여가 같은 카드 피해에 선적용 assert.equal(r.turns, 1); }); +test('simulateCombat: firstCardDamageBonus가 턴 첫 카드에 적용 (kind===Attack, Lua 동기화)', () => { + // ChargedBlow처럼 class=warrior·kind=Attack인 카드의 첫-카드 보너스. + // 게이트가 class==="Attack"이면 영구 false라 미발동(버그) → 5뎀/2턴. + // kind==="Attack"이면 5+2=7 → 1턴 처치. + const data = { + cards: { CB: { name: '차지블로우', cost: 3, kind: 'Attack', class: 'warrior', damage: 5, firstCardDamageBonus: 2 } }, + starterDeck: ['CB', 'CB', 'CB', 'CB', 'CB'], + monsters: [{ name: '적', maxHp: 7, intents: [{ kind: 'Defend', value: 0 }] }], + }; + const r = simulateCombat(data, mulberry32(1)); + assert.equal(r.turns, 1); +}); + test('simulateCombat: Power(매턴 힘) 누적', () => { const data = { cards: { diff --git a/tools/deck/cb/hand.mjs b/tools/deck/cb/hand.mjs index bebd5b7..b3c9ffd 100644 --- a/tools/deck/cb/hand.mjs +++ b/tools/deck/cb/hand.mjs @@ -347,7 +347,7 @@ end if c.damagePerCardDrawnThisCombat ~= nil then base2 = base2 + (self.CardsDrawnThisCombat or 0) * c.damagePerCardDrawnThisCombat end -if c.class == "Attack" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then +if c.kind == "Attack" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then base2 = base2 + c.firstCardDamageBonus end if c.class == "shiv" then