feat(cards): implement retain keyword
This commit is contained in:
@@ -212,7 +212,7 @@ export function simulateCombat(data, rng, stats) {
|
||||
else if (pc.powerEffect === 'energyPerTurn') energyBonus += pc.value;
|
||||
else if (pc.powerEffect === 'blockPerTurn') pBlock += pc.value;
|
||||
}
|
||||
let energy = ENERGY + energyBonus; hand = []; draw(HAND_SIZE);
|
||||
let energy = ENERGY + energyBonus; draw(HAND_SIZE);
|
||||
while (true) {
|
||||
const alive = aliveList();
|
||||
if (alive.length === 0) break;
|
||||
@@ -230,7 +230,13 @@ export function simulateCombat(data, rng, stats) {
|
||||
let burn = 0;
|
||||
for (const hid of hand) { const hc = cards[hid]; if (hc && hc.endTurnDamage) burn += hc.endTurnDamage; }
|
||||
if (burn > 0) { pHp -= burn; if (pHp < 0) pHp = 0; }
|
||||
discard.push(...hand); hand = [];
|
||||
const kept = [];
|
||||
for (const hid of hand) {
|
||||
const hc = cards[hid];
|
||||
if (hc?.retain === true) kept.push(hid);
|
||||
else discard.push(hid);
|
||||
}
|
||||
hand = kept;
|
||||
if (pHp <= 0) return { win: false, turns, playerHpRemaining: 0 };
|
||||
// 플레이어 디버프 감소 — Lua EndPlayerTurn 동기화 (적 행동 전)
|
||||
if (pWeak > 0) pWeak--;
|
||||
|
||||
@@ -390,3 +390,18 @@ test("simulateCombat: sly discarded card resolves for free", () => {
|
||||
assert.equal(r.win, true);
|
||||
assert.equal(r.turns, 1);
|
||||
});
|
||||
|
||||
test("simulateCombat: retain keeps card in hand across turns", () => {
|
||||
const data = {
|
||||
cards: {
|
||||
Boost: { name: "Boost", cost: 3, kind: "Power", powerEffect: "energyPerTurn", value: 98 },
|
||||
Hold: { name: "Hold", cost: 100, kind: "Attack", damage: 10, retain: true },
|
||||
Blank: { name: "Blank", cost: 99, kind: "Skill", block: 0 },
|
||||
},
|
||||
starterDeck: ["Blank", "Blank", "Blank", "Blank", "Blank", "Boost", "Hold", "Blank", "Blank", "Blank"],
|
||||
monsters: [{ name: "Dummy", maxHp: 10, intents: [{ kind: "Defend", value: 0 }] }],
|
||||
};
|
||||
const r = simulateCombat(data, () => 0.999999);
|
||||
assert.equal(r.win, true);
|
||||
assert.equal(r.turns, 2);
|
||||
});
|
||||
|
||||
@@ -152,6 +152,7 @@ function luaCardsTable(cards) {
|
||||
if (c.discard != null) fields.push(`discard = ${c.discard}`);
|
||||
if (c.discardAll === true) fields.push('discardAll = true');
|
||||
if (c.sly === true) fields.push('sly = true');
|
||||
if (c.retain === true) fields.push('retain = true');
|
||||
if (c.aoe === true) fields.push('aoe = true');
|
||||
if (c.unplayable === true) fields.push('unplayable = true');
|
||||
if (c.curse === true) fields.push('curse = true');
|
||||
@@ -3701,10 +3702,17 @@ if burn > 0 then
|
||||
\tself:ShowPlayerDmgPop(burn)
|
||||
\tself:RenderCombat()
|
||||
end
|
||||
local kept = {}
|
||||
for i = 1, #self.Hand do
|
||||
\ttable.insert(self.DiscardPile, self.Hand[i])
|
||||
\tlocal cardId = self.Hand[i]
|
||||
\tlocal c = self.Cards[cardId]
|
||||
\tif c ~= nil and c.retain == true then
|
||||
\t\ttable.insert(kept, cardId)
|
||||
\telse
|
||||
\t\ttable.insert(self.DiscardPile, cardId)
|
||||
\tend
|
||||
end
|
||||
self.Hand = {}
|
||||
self.Hand = kept
|
||||
if self.PlayerWeak > 0 then self.PlayerWeak = self.PlayerWeak - 1 end
|
||||
if self.PlayerVuln > 0 then self.PlayerVuln = self.PlayerVuln - 1 end
|
||||
self:RenderHand(false)
|
||||
|
||||
Reference in New Issue
Block a user