Revert "Merge branch 'main' of https://gitea.gahusb.synology.me/gahusb/maplecontest"
This reverts commit17200d47ec, reversing changes made to95d6155086.
This commit is contained in:
@@ -55,8 +55,7 @@ export function calcAttack(base, str, weak, vulnOnTarget) {
|
||||
}
|
||||
|
||||
export function calcEnemyAttack(base, str, weak, vulnOnTarget, strengthLoss = 0) {
|
||||
// Lua EnemyActStep 동기화: 힘 손실은 (value+str) 전체에서 차감(음수 힘 허용), 최종 calcAttack이 0 클램프.
|
||||
return calcAttack(base, str - strengthLoss, weak, vulnOnTarget);
|
||||
return calcAttack(base, Math.max(0, str - strengthLoss), weak, vulnOnTarget);
|
||||
}
|
||||
|
||||
// 방어 우선 차감 후 hp 적용 → { hp, block }
|
||||
@@ -343,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.kind === 'Attack' && turnCardsPlayedThisTurn === 0 && c.firstCardDamageBonus) base += c.firstCardDamageBonus;
|
||||
if (c.class === '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');
|
||||
@@ -423,9 +422,6 @@ export function simulateCombat(data, rng, stats) {
|
||||
const hitN = (c.hits || 1) + bonusHits;
|
||||
let useAoe = c.aoe === true;
|
||||
if (c.class === 'shiv' && shivAoeThisCombat === true) useAoe = true;
|
||||
if (c.class === 'shiv' && !shivFirstDamageBonusUsed && powerFieldTotal('firstShivDamageBonus') > 0) {
|
||||
shivFirstDamageBonusUsed = true;
|
||||
}
|
||||
const perHit = calcAttack(baseDamage || 0, pStr, pWeak, 0) * turnAttackMultiplier;
|
||||
const dealToTarget = (target, amount) => {
|
||||
if (!target || !target.alive) return { killed: false, dealt: 0 };
|
||||
@@ -519,6 +515,9 @@ export function simulateCombat(data, rng, stats) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.class === 'shiv' && !shivFirstDamageBonusUsed && powerFieldTotal('firstShivDamageBonus') > 0) {
|
||||
shivFirstDamageBonusUsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.strength) pStr += c.strength;
|
||||
@@ -565,7 +564,7 @@ export function simulateCombat(data, rng, stats) {
|
||||
}
|
||||
}
|
||||
if (c.blockPerDamageDealtThisTurn && c.blockPerDamageDealtThisTurn > 0 && c.kind !== 'Power') {
|
||||
blockGained += addBlock(Math.max(0, damageDealtThisTurn * c.blockPerDamageDealtThisTurn));
|
||||
blockGained += Math.max(0, damageDealtThisTurn * c.blockPerDamageDealtThisTurn);
|
||||
}
|
||||
if (recordStats && stats) stats[id] = bump(stats[id], costSpent, dmg, blockGained);
|
||||
}
|
||||
@@ -659,7 +658,7 @@ export function simulateCombat(data, rng, stats) {
|
||||
const baseCost = c.cost || 0;
|
||||
const combatReduction = combatCardCostReduction[id] || 0;
|
||||
const cost = handCostZeroThisTurn === true ? 0 : (c.useAllEnergy === true ? energy : (skillFree ? 0 : (c.kind === 'Skill' ? Math.max(0, baseCost - skillCostReductionThisTurn) : baseCost)));
|
||||
const finalCost = c.useAllEnergy === true ? cost : Math.max(0, cost - combatReduction);
|
||||
const finalCost = Math.max(0, cost - combatReduction);
|
||||
energy -= finalCost;
|
||||
resolveCardEffects(id, c, finalCost);
|
||||
const playedBlock = powerFieldTotal('cardPlayedBlock');
|
||||
@@ -722,7 +721,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 = calcEnemyAttack(it.value, m.str, m.weak, pVuln, enemyStrengthLossThisTurn);
|
||||
const atk = calcAttack(it.value, Math.max(0, m.str - enemyStrengthLossThisTurn), m.weak, pVuln);
|
||||
const beforeHp = pHp;
|
||||
let incoming = atk;
|
||||
if (pIntangible > 0 && incoming > 1) incoming = 1;
|
||||
|
||||
@@ -262,19 +262,6 @@ 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: {
|
||||
@@ -895,44 +882,6 @@ 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: firstShivDamageBonus는 턴당 첫 Shiv에만 적용 (Lua 동기화)', () => {
|
||||
// PhantomBlades(firstShivDamageBonus 9) 활성. 턴당 3 Shiv 사용(에너지3·cost1).
|
||||
// 정답(첫 Shiv만 +9): 턴1 = 10+1+1=12 → 13HP에 1 남김 → 2턴.
|
||||
// 버그(모든 Shiv +9): 턴1 = 10*3=30 → 1턴.
|
||||
const data = {
|
||||
cards: {
|
||||
PhantomBlades: { name: '환영검', cost: 0, kind: 'Power', firstShivDamageBonus: 9 },
|
||||
Shiv: { name: '시브', cost: 1, kind: 'Attack', class: 'shiv', damage: 1 },
|
||||
},
|
||||
starterDeck: ['PhantomBlades', 'Shiv', 'Shiv', 'Shiv', 'Shiv'],
|
||||
monsters: [{ name: '적', maxHp: 13, intents: [{ kind: 'Attack', value: 0 }] }],
|
||||
};
|
||||
const r = simulateCombat(data, mulberry32(1));
|
||||
assert.equal(r.turns, 2);
|
||||
});
|
||||
|
||||
test('simulateCombat: blockPerDamageDealtThisTurn이 실제 방어를 부여 (Lua 동기화)', () => {
|
||||
// 매턴 Hit(5뎀) → Guard(준 피해만큼 방어 5) → 적 공격 5 상쇄.
|
||||
// 수정(실제 방어): 무한 생존 → 무승부. 버그(방어 미부여): 매턴 5피해 → 사망.
|
||||
const data = {
|
||||
cards: {
|
||||
Hit: { name: '타격', cost: 2, kind: 'Attack', damage: 5 },
|
||||
Guard: { name: '대비', cost: 1, kind: 'Skill', blockPerDamageDealtThisTurn: 1 },
|
||||
},
|
||||
starterDeck: ['Hit', 'Guard'],
|
||||
monsters: [{ name: '적', maxHp: 9999, intents: [{ kind: 'Attack', value: 5 }] }],
|
||||
};
|
||||
const r = simulateCombat(data, mulberry32(1));
|
||||
assert.equal(r.draw, true);
|
||||
});
|
||||
|
||||
test("simulateCombat: repeatOnKill repeats an attack until no kill occurs", () => {
|
||||
const shared = {
|
||||
cards: {
|
||||
|
||||
Reference in New Issue
Block a user