diff --git a/tools/balance/sim-balance.mjs b/tools/balance/sim-balance.mjs index 3cd2b2b..c783ac6 100644 --- a/tools/balance/sim-balance.mjs +++ b/tools/balance/sim-balance.mjs @@ -55,7 +55,8 @@ export function calcAttack(base, str, weak, vulnOnTarget) { } export function calcEnemyAttack(base, str, weak, vulnOnTarget, strengthLoss = 0) { - return calcAttack(base, Math.max(0, str - strengthLoss), weak, vulnOnTarget); + // Lua EnemyActStep 동기화: 힘 손실은 (value+str) 전체에서 차감(음수 힘 허용), 최종 calcAttack이 0 클램프. + return calcAttack(base, str - strengthLoss, weak, vulnOnTarget); } // 방어 우선 차감 후 hp 적용 → { hp, block } @@ -721,7 +722,7 @@ export function simulateCombat(data, rng, stats) { const it = m.intents.length ? m.intents[Math.floor(rng() * m.intents.length)] : null; if (it) { if (it.kind === 'Attack') { - const atk = calcAttack(it.value, Math.max(0, m.str - enemyStrengthLossThisTurn), m.weak, pVuln); + const atk = calcEnemyAttack(it.value, m.str, m.weak, pVuln, enemyStrengthLossThisTurn); const beforeHp = pHp; let incoming = atk; if (pIntangible > 0 && incoming > 1) incoming = 1; diff --git a/tools/balance/sim-balance.test.mjs b/tools/balance/sim-balance.test.mjs index dabeab9..fe44e5e 100644 --- a/tools/balance/sim-balance.test.mjs +++ b/tools/balance/sim-balance.test.mjs @@ -895,6 +895,13 @@ test("calcEnemyAttack: enemyStrengthLossThisTurn reduces enemy attack damage", ( assert.equal(calcEnemyAttack(10, 6, 0, 0, 0), 16); }); +test("calcEnemyAttack: 힘 손실이 base 아래로 공격을 낮춘다 (음수 힘, Lua 동기화)", () => { + // 적 str=0, loss=6 → 힘 -6 → 10-6=4. JS가 str을 0에서 클램프하면 10(버그). Lua는 전체에서 차감. + assert.equal(calcEnemyAttack(10, 0, 0, 0, 6), 4); + assert.equal(calcEnemyAttack(10, 3, 0, 0, 6), 7); + assert.equal(calcEnemyAttack(5, 0, 0, 0, 6), 0); // 5-6=-1 → 0 클램프 +}); + test("simulateCombat: repeatOnKill repeats an attack until no kill occurs", () => { const shared = { cards: {