Fix damage pop UI paths and card hover tooltip support

This commit is contained in:
2026-07-13 01:59:11 +09:00
parent 84381947be
commit 1029459f23
22 changed files with 4569 additions and 878 deletions

View File

@@ -100,7 +100,7 @@ const SOUL_UNLOCKS = [
{ key: 'relic', name: '유물 수집가', desc: '런 시작 시 유물 1개 추가', cost: 6 },
];
function luaSoulShopTable(unlocks) {
const items = unlocks.map((u) => `\t{ key = ${luaStr(u.key)}, name = ${luaStr(u.name)}, desc = ${luaStr(u.desc)}, cost = ${u.cost} },`).join('\n');
const items = unlocks.map((u) => `\t{ key = ${luaStr(u.key)}, name = ${luaStr(u.name)}, desc = ${luaStr(u.desc)}, cost = ${luaNum(u.cost)} },`).join('\n');
return `self.SoulShopDef = {\n${items}\n}`;
}
if (!ENEMIES.enemies[ENEMIES.activeEnemy]) {
@@ -165,7 +165,7 @@ for (const id of RELICS.relicPool) {
}
function luaRelicsTable(relics) {
const lines = Object.entries(relics).map(([id, r]) =>
`\t${id} = { name = ${luaStr(r.name)}, desc = ${luaStr(r.desc)}, hook = ${luaStr(r.hook)}, effect = ${luaStr(r.effect)}, value = ${r.value}, icon = ${luaStr(r.icon || '')} },`);
`\t${id} = { name = ${luaStr(r.name)}, desc = ${luaStr(r.desc)}, hook = ${luaStr(r.hook)}, effect = ${luaStr(r.effect)}, value = ${luaNum(r.value)}, icon = ${luaStr(r.icon || '')} },`);
return `self.Relics = {\n${lines.join('\n')}\n}`;
}
@@ -175,32 +175,38 @@ for (const [pid, p] of Object.entries(POTIONS.potions)) {
}
function luaPotionsTable(potions) {
const lines = Object.entries(potions).map(([id, p]) =>
`\t${id} = { name = ${luaStr(p.name)}, desc = ${luaStr(p.desc)}, effect = ${luaStr(p.effect)}, value = ${p.value}, icon = ${luaStr(p.icon || '')} },`);
`\t${id} = { name = ${luaStr(p.name)}, desc = ${luaStr(p.desc)}, effect = ${luaStr(p.effect)}, value = ${luaNum(p.value)}, icon = ${luaStr(p.icon || '')} },`);
return `self.Potions = {\n${lines.join('\n')}\n}`;
}
function luaIntentsArray(intents) {
return '{ ' + intents.map((it) => {
const fields = [`kind = ${luaStr(it.kind)}`, `value = ${it.value != null ? it.value : 0}`];
const fields = [`kind = ${luaStr(it.kind)}`, `value = ${luaNum(it.value != null ? it.value : 0)}`];
if (it.effect != null) fields.push(`effect = ${luaStr(it.effect)}`);
if (it.card != null) fields.push(`card = ${luaStr(it.card)}`);
if (it.count != null) fields.push(`count = ${it.count}`);
if (it.count != null) fields.push(`count = ${luaNum(it.count)}`);
return `{ ${fields.join(', ')} }`;
}).join(', ') + ' }';
}
function luaEnemiesTable(enemies) {
const lines = Object.entries(enemies).map(([id, e]) =>
`\t${id} = { name = ${luaStr(e.name)}, maxHp = ${e.maxHp}, intents = ${luaIntentsArray(e.intents)} },`);
`\t${id} = { name = ${luaStr(e.name)}, maxHp = ${luaNum(e.maxHp)}, intents = ${luaIntentsArray(e.intents)} },`);
return `self.Enemies = {\n${lines.join('\n')}\n}`;
}
function luaStr(s) {
return '"' + String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"';
}
function luaNum(n) {
const v = Number(n);
if (!Number.isFinite(v)) return '0';
if (Number.isInteger(v)) return String(v);
return String(v);
}
function luaJobsTable(jobs) {
const cls = Object.entries(jobs).map(([clsId, list]) => {
const items = list.map((j) =>
`\t\t{ id = ${luaStr(j.id)}, name = ${luaStr(j.name)}, desc = ${luaStr(j.desc)}, starter = ${luaStr(j.starter)}, tier = ${j.tier ?? 2}, parent = ${luaStr(j.parent ?? clsId)} },`).join('\n');
`\t\t{ id = ${luaStr(j.id)}, name = ${luaStr(j.name)}, desc = ${luaStr(j.desc)}, starter = ${luaStr(j.starter)}, tier = ${luaNum(j.tier ?? 2)}, parent = ${luaStr(j.parent ?? clsId)} },`).join('\n');
return `\t${clsId} = {\n${items}\n\t},`;
}).join('\n');
return `self.Jobs = {\n${cls}\n}`;
@@ -217,133 +223,133 @@ function luaClassLineagesTable(lineages) {
}
function luaJobMetaTable(meta) {
const rows = Object.entries(meta).map(([jobId, entry]) =>
`\t${jobId} = { name = ${luaStr(entry.name)}, starter = ${luaStr(entry.starter)}, tier = ${entry.tier}, parent = ${luaStr(entry.parent)}, sourceClass = ${luaStr(entry.sourceClass)} },`);
`\t${jobId} = { name = ${luaStr(entry.name)}, starter = ${luaStr(entry.starter)}, tier = ${luaNum(entry.tier)}, parent = ${luaStr(entry.parent)}, sourceClass = ${luaStr(entry.sourceClass)} },`);
return `self.JobMeta = {\n${rows.join('\n')}\n}`;
}
function luaCardsTable(cards) {
const lines = Object.entries(cards).map(([id, c]) => {
const fields = [`name = ${luaStr(c.name)}`, `cost = ${c.cost}`, `desc = ${luaStr(c.desc)}`, `kind = ${luaStr(c.kind)}`];
if (c.damage != null) fields.push(`damage = ${c.damage}`);
if (c.damageFromCurrentBlock != null) fields.push(`damageFromCurrentBlock = ${c.damageFromCurrentBlock}`);
if (c.damagePerCombo != null) fields.push(`damagePerCombo = ${c.damagePerCombo}`);
if (c.damagePerHolyCharge != null) fields.push(`damagePerHolyCharge = ${c.damagePerHolyCharge}`);
if (c.attackDamagePerCombo != null) fields.push(`attackDamagePerCombo = ${c.attackDamagePerCombo}`);
const fields = [`name = ${luaStr(c.name)}`, `cost = ${luaNum(c.cost)}`, `desc = ${luaStr(c.desc)}`, `kind = ${luaStr(c.kind)}`];
if (c.damage != null) fields.push(`damage = ${luaNum(c.damage)}`);
if (c.damageFromCurrentBlock != null) fields.push(`damageFromCurrentBlock = ${luaNum(c.damageFromCurrentBlock)}`);
if (c.damagePerCombo != null) fields.push(`damagePerCombo = ${luaNum(c.damagePerCombo)}`);
if (c.damagePerHolyCharge != null) fields.push(`damagePerHolyCharge = ${luaNum(c.damagePerHolyCharge)}`);
if (c.attackDamagePerCombo != null) fields.push(`attackDamagePerCombo = ${luaNum(c.attackDamagePerCombo)}`);
if (c.damageNameMatch != null) fields.push(`damageNameMatch = ${luaStr(c.damageNameMatch)}`);
if (c.damagePerOwnedNameMatch != null) fields.push(`damagePerOwnedNameMatch = ${c.damagePerOwnedNameMatch}`);
if (c.damagePerOtherHandCard != null) fields.push(`damagePerOtherHandCard = ${c.damagePerOtherHandCard}`);
if (c.damagePerAttackPlayedThisTurn != null) fields.push(`damagePerAttackPlayedThisTurn = ${c.damagePerAttackPlayedThisTurn}`);
if (c.damagePerDiscardedThisTurn != null) fields.push(`damagePerDiscardedThisTurn = ${c.damagePerDiscardedThisTurn}`);
if (c.damagePerSkillInHand != null) fields.push(`damagePerSkillInHand = ${c.damagePerSkillInHand}`);
if (c.damagePerCardDrawnThisCombat != null) fields.push(`damagePerCardDrawnThisCombat = ${c.damagePerCardDrawnThisCombat}`);
if (c.damagePerTurn != null) fields.push(`damagePerTurn = ${c.damagePerTurn}`);
if (c.cardPlayedDamage != null) fields.push(`cardPlayedDamage = ${c.cardPlayedDamage}`);
if (c.cardPlayedRandomDamage != null) fields.push(`cardPlayedRandomDamage = ${c.cardPlayedRandomDamage}`);
if (c.attackPlayedDamage != null) fields.push(`attackPlayedDamage = ${c.attackPlayedDamage}`);
if (c.firstCardDamageBonus != null) fields.push(`firstCardDamageBonus = ${c.firstCardDamageBonus}`);
if (c.rewardOnKill != null) fields.push(`rewardOnKill = ${c.rewardOnKill}`);
if (c.maxHpOnKill != null) fields.push(`maxHpOnKill = ${c.maxHpOnKill}`);
if (c.intangible != null) fields.push(`intangible = ${c.intangible}`);
if (c.endTurnDexLoss != null) fields.push(`endTurnDexLoss = ${c.endTurnDexLoss}`);
if (c.poisonPerTurn != null) fields.push(`poisonPerTurn = ${c.poisonPerTurn}`);
if (c.attackPoison != null) fields.push(`attackPoison = ${c.attackPoison}`);
if (c.otherHandAtLeast != null) fields.push(`otherHandAtLeast = ${c.otherHandAtLeast}`);
if (c.bonusHitsWhenOtherHandAtLeast != null) fields.push(`bonusHitsWhenOtherHandAtLeast = ${c.bonusHitsWhenOtherHandAtLeast}`);
if (c.block != null) fields.push(`block = ${c.block}`);
if (c.blockGainMultiplier != null) fields.push(`blockGainMultiplier = ${c.blockGainMultiplier}`);
if (c.blockPerDamageDealtThisTurn != null) fields.push(`blockPerDamageDealtThisTurn = ${c.blockPerDamageDealtThisTurn}`);
if (c.strength != null) fields.push(`strength = ${c.strength}`);
if (c.dex != null) fields.push(`dex = ${c.dex}`);
if (c.thorns != null) fields.push(`thorns = ${c.thorns}`);
if (c.cardPlayedBlock != null) fields.push(`cardPlayedBlock = ${c.cardPlayedBlock}`);
if (c.comboOnAttack != null) fields.push(`comboOnAttack = ${c.comboOnAttack}`);
if (c.comboMax != null) fields.push(`comboMax = ${c.comboMax}`);
if (c.attackWeak != null) fields.push(`attackWeak = ${c.attackWeak}`);
if (c.holyChargeOnHolyForce != null) fields.push(`holyChargeOnHolyForce = ${c.holyChargeOnHolyForce}`);
if (c.holyChargeMax != null) fields.push(`holyChargeMax = ${c.holyChargeMax}`);
if (c.damageTakenReduction != null) fields.push(`damageTakenReduction = ${c.damageTakenReduction}`);
if (c.blockOnDamaged != null) fields.push(`blockOnDamaged = ${c.blockOnDamaged}`);
if (c.strengthOnDamagedOnce != null) fields.push(`strengthOnDamagedOnce = ${c.strengthOnDamagedOnce}`);
if (c.drawOnExhaust != null) fields.push(`drawOnExhaust = ${c.drawOnExhaust}`);
if (c.damagePerOwnedNameMatch != null) fields.push(`damagePerOwnedNameMatch = ${luaNum(c.damagePerOwnedNameMatch)}`);
if (c.damagePerOtherHandCard != null) fields.push(`damagePerOtherHandCard = ${luaNum(c.damagePerOtherHandCard)}`);
if (c.damagePerAttackPlayedThisTurn != null) fields.push(`damagePerAttackPlayedThisTurn = ${luaNum(c.damagePerAttackPlayedThisTurn)}`);
if (c.damagePerDiscardedThisTurn != null) fields.push(`damagePerDiscardedThisTurn = ${luaNum(c.damagePerDiscardedThisTurn)}`);
if (c.damagePerSkillInHand != null) fields.push(`damagePerSkillInHand = ${luaNum(c.damagePerSkillInHand)}`);
if (c.damagePerCardDrawnThisCombat != null) fields.push(`damagePerCardDrawnThisCombat = ${luaNum(c.damagePerCardDrawnThisCombat)}`);
if (c.damagePerTurn != null) fields.push(`damagePerTurn = ${luaNum(c.damagePerTurn)}`);
if (c.cardPlayedDamage != null) fields.push(`cardPlayedDamage = ${luaNum(c.cardPlayedDamage)}`);
if (c.cardPlayedRandomDamage != null) fields.push(`cardPlayedRandomDamage = ${luaNum(c.cardPlayedRandomDamage)}`);
if (c.attackPlayedDamage != null) fields.push(`attackPlayedDamage = ${luaNum(c.attackPlayedDamage)}`);
if (c.firstCardDamageBonus != null) fields.push(`firstCardDamageBonus = ${luaNum(c.firstCardDamageBonus)}`);
if (c.rewardOnKill != null) fields.push(`rewardOnKill = ${luaNum(c.rewardOnKill)}`);
if (c.maxHpOnKill != null) fields.push(`maxHpOnKill = ${luaNum(c.maxHpOnKill)}`);
if (c.intangible != null) fields.push(`intangible = ${luaNum(c.intangible)}`);
if (c.endTurnDexLoss != null) fields.push(`endTurnDexLoss = ${luaNum(c.endTurnDexLoss)}`);
if (c.poisonPerTurn != null) fields.push(`poisonPerTurn = ${luaNum(c.poisonPerTurn)}`);
if (c.attackPoison != null) fields.push(`attackPoison = ${luaNum(c.attackPoison)}`);
if (c.otherHandAtLeast != null) fields.push(`otherHandAtLeast = ${luaNum(c.otherHandAtLeast)}`);
if (c.bonusHitsWhenOtherHandAtLeast != null) fields.push(`bonusHitsWhenOtherHandAtLeast = ${luaNum(c.bonusHitsWhenOtherHandAtLeast)}`);
if (c.block != null) fields.push(`block = ${luaNum(c.block)}`);
if (c.blockGainMultiplier != null) fields.push(`blockGainMultiplier = ${luaNum(c.blockGainMultiplier)}`);
if (c.blockPerDamageDealtThisTurn != null) fields.push(`blockPerDamageDealtThisTurn = ${luaNum(c.blockPerDamageDealtThisTurn)}`);
if (c.strength != null) fields.push(`strength = ${luaNum(c.strength)}`);
if (c.dex != null) fields.push(`dex = ${luaNum(c.dex)}`);
if (c.thorns != null) fields.push(`thorns = ${luaNum(c.thorns)}`);
if (c.cardPlayedBlock != null) fields.push(`cardPlayedBlock = ${luaNum(c.cardPlayedBlock)}`);
if (c.comboOnAttack != null) fields.push(`comboOnAttack = ${luaNum(c.comboOnAttack)}`);
if (c.comboMax != null) fields.push(`comboMax = ${luaNum(c.comboMax)}`);
if (c.attackWeak != null) fields.push(`attackWeak = ${luaNum(c.attackWeak)}`);
if (c.holyChargeOnHolyForce != null) fields.push(`holyChargeOnHolyForce = ${luaNum(c.holyChargeOnHolyForce)}`);
if (c.holyChargeMax != null) fields.push(`holyChargeMax = ${luaNum(c.holyChargeMax)}`);
if (c.damageTakenReduction != null) fields.push(`damageTakenReduction = ${luaNum(c.damageTakenReduction)}`);
if (c.blockOnDamaged != null) fields.push(`blockOnDamaged = ${luaNum(c.blockOnDamaged)}`);
if (c.strengthOnDamagedOnce != null) fields.push(`strengthOnDamagedOnce = ${luaNum(c.strengthOnDamagedOnce)}`);
if (c.drawOnExhaust != null) fields.push(`drawOnExhaust = ${luaNum(c.drawOnExhaust)}`);
if (c.drawNameMatchAutoPlay != null) fields.push(`drawNameMatchAutoPlay = ${luaStr(c.drawNameMatchAutoPlay)}`);
if (c.weak != null) fields.push(`weak = ${c.weak}`);
if (c.vuln != null) fields.push(`vuln = ${c.vuln}`);
if (c.weak != null) fields.push(`weak = ${luaNum(c.weak)}`);
if (c.vuln != null) fields.push(`vuln = ${luaNum(c.vuln)}`);
if (c.powerEffect != null) fields.push(`powerEffect = ${luaStr(c.powerEffect)}`);
if (c.value != null) fields.push(`value = ${c.value}`);
if (c.value != null) fields.push(`value = ${luaNum(c.value)}`);
if (!c.class) throw new Error(`[gen-slaydeck] 카드 ${id}에 class 누락`);
fields.push(`class = ${luaStr(c.class)}`);
fields.push(`rarity = ${luaStr(c.rarity)}`);
if (c.hits != null) fields.push(`hits = ${c.hits}`);
if (c.hits != null) fields.push(`hits = ${luaNum(c.hits)}`);
if (c.pierce === true) fields.push('pierce = true');
if (c.selfVuln != null) fields.push(`selfVuln = ${c.selfVuln}`);
if (c.draw != null) fields.push(`draw = ${c.draw}`);
if (c.drawUntilHandSize != null) fields.push(`drawUntilHandSize = ${c.drawUntilHandSize}`);
if (c.drawSkillBlock != null) fields.push(`drawSkillBlock = ${c.drawSkillBlock}`);
if (c.drawDamage != null) fields.push(`drawDamage = ${c.drawDamage}`);
if (c.drawPoison != null) fields.push(`drawPoison = ${c.drawPoison}`);
if (c.selfVuln != null) fields.push(`selfVuln = ${luaNum(c.selfVuln)}`);
if (c.draw != null) fields.push(`draw = ${luaNum(c.draw)}`);
if (c.drawUntilHandSize != null) fields.push(`drawUntilHandSize = ${luaNum(c.drawUntilHandSize)}`);
if (c.drawSkillBlock != null) fields.push(`drawSkillBlock = ${luaNum(c.drawSkillBlock)}`);
if (c.drawDamage != null) fields.push(`drawDamage = ${luaNum(c.drawDamage)}`);
if (c.drawPoison != null) fields.push(`drawPoison = ${luaNum(c.drawPoison)}`);
if (c.exhaustHandNonAttack === true) fields.push('exhaustHandNonAttack = true');
if (c.exhaustHandAll === true) fields.push('exhaustHandAll = true');
if (c.drawPerExhausted != null) fields.push(`drawPerExhausted = ${c.drawPerExhausted}`);
if (c.blockPerExhaustedCard != null) fields.push(`blockPerExhaustedCard = ${c.blockPerExhaustedCard}`);
if (c.addRandomCardCount != null) fields.push(`addRandomCardCount = ${c.addRandomCardCount}`);
if (c.addRandomCardPerExhausted != null) fields.push(`addRandomCardPerExhausted = ${c.addRandomCardPerExhausted}`);
if (c.drawPerExhausted != null) fields.push(`drawPerExhausted = ${luaNum(c.drawPerExhausted)}`);
if (c.blockPerExhaustedCard != null) fields.push(`blockPerExhaustedCard = ${luaNum(c.blockPerExhaustedCard)}`);
if (c.addRandomCardCount != null) fields.push(`addRandomCardCount = ${luaNum(c.addRandomCardCount)}`);
if (c.addRandomCardPerExhausted != null) fields.push(`addRandomCardPerExhausted = ${luaNum(c.addRandomCardPerExhausted)}`);
if (c.addRandomCardKind != null) fields.push(`addRandomCardKind = ${luaStr(c.addRandomCardKind)}`);
if (c.addRandomCardSameClass === true) fields.push('addRandomCardSameClass = true');
if (c.addedCardsCostZeroThisTurn === true) fields.push('addedCardsCostZeroThisTurn = true');
if (c.playTopDrawPileCount != null) fields.push(`playTopDrawPileCount = ${c.playTopDrawPileCount}`);
if (c.playTopDrawPileCountPerEnergy != null) fields.push(`playTopDrawPileCountPerEnergy = ${c.playTopDrawPileCountPerEnergy}`);
if (c.heal != null) fields.push(`heal = ${c.heal}`);
if (c.healPerHolyCharge != null) fields.push(`healPerHolyCharge = ${c.healPerHolyCharge}`);
if (c.gainEnergy != null) fields.push(`gainEnergy = ${c.gainEnergy}`);
if (c.comboGain != null) fields.push(`comboGain = ${c.comboGain}`);
if (c.playTopDrawPileCount != null) fields.push(`playTopDrawPileCount = ${luaNum(c.playTopDrawPileCount)}`);
if (c.playTopDrawPileCountPerEnergy != null) fields.push(`playTopDrawPileCountPerEnergy = ${luaNum(c.playTopDrawPileCountPerEnergy)}`);
if (c.heal != null) fields.push(`heal = ${luaNum(c.heal)}`);
if (c.healPerHolyCharge != null) fields.push(`healPerHolyCharge = ${luaNum(c.healPerHolyCharge)}`);
if (c.gainEnergy != null) fields.push(`gainEnergy = ${luaNum(c.gainEnergy)}`);
if (c.comboGain != null) fields.push(`comboGain = ${luaNum(c.comboGain)}`);
if (c.removePlayerDebuffs === true) fields.push('removePlayerDebuffs = true');
if (c.holyForce === true) fields.push('holyForce = true');
if (c.holyChargeGain != null) fields.push(`holyChargeGain = ${c.holyChargeGain}`);
if (c.blockPerHolyCharge != null) fields.push(`blockPerHolyCharge = ${c.blockPerHolyCharge}`);
if (c.holyChargeGain != null) fields.push(`holyChargeGain = ${luaNum(c.holyChargeGain)}`);
if (c.blockPerHolyCharge != null) fields.push(`blockPerHolyCharge = ${luaNum(c.blockPerHolyCharge)}`);
if (c.holyChargeSpendAll === true) fields.push('holyChargeSpendAll = true');
if (c.poison != null) fields.push(`poison = ${c.poison}`);
if (c.discard != null) fields.push(`discard = ${c.discard}`);
if (c.poison != null) fields.push(`poison = ${luaNum(c.poison)}`);
if (c.discard != null) fields.push(`discard = ${luaNum(c.discard)}`);
if (c.discardAll === true) fields.push('discardAll = true');
if (c.drawPerDiscarded != null) fields.push(`drawPerDiscarded = ${c.drawPerDiscarded}`);
if (c.addShiv != null) fields.push(`addShiv = ${c.addShiv}`);
if (c.turnStartShiv != null) fields.push(`turnStartShiv = ${c.turnStartShiv}`);
if (c.turnStartDraw != null) fields.push(`turnStartDraw = ${c.turnStartDraw}`);
if (c.turnStartDiscard != null) fields.push(`turnStartDiscard = ${c.turnStartDiscard}`);
if (c.drawPerDiscarded != null) fields.push(`drawPerDiscarded = ${luaNum(c.drawPerDiscarded)}`);
if (c.addShiv != null) fields.push(`addShiv = ${luaNum(c.addShiv)}`);
if (c.turnStartShiv != null) fields.push(`turnStartShiv = ${luaNum(c.turnStartShiv)}`);
if (c.turnStartDraw != null) fields.push(`turnStartDraw = ${luaNum(c.turnStartDraw)}`);
if (c.turnStartDiscard != null) fields.push(`turnStartDiscard = ${luaNum(c.turnStartDiscard)}`);
if (c.handCostZeroThisTurn === true) fields.push('handCostZeroThisTurn = true');
if (c.drawDisabledThisTurn === true) fields.push('drawDisabledThisTurn = true');
if (c.addShivPerDiscard === true) fields.push('addShivPerDiscard = true');
if (c.useAllEnergy === true) fields.push('useAllEnergy = true');
if (c.shivDamageBonus != null) fields.push(`shivDamageBonus = ${c.shivDamageBonus}`);
if (c.firstShivDamageBonus != null) fields.push(`firstShivDamageBonus = ${c.firstShivDamageBonus}`);
if (c.shivDamageBonus != null) fields.push(`shivDamageBonus = ${luaNum(c.shivDamageBonus)}`);
if (c.firstShivDamageBonus != null) fields.push(`firstShivDamageBonus = ${luaNum(c.firstShivDamageBonus)}`);
if (c.shivRetain === true) fields.push('shivRetain = true');
if (c.shivAoe === true) fields.push('shivAoe = true');
if (c.attackDamageVsWeakMultiplier != null) fields.push(`attackDamageVsWeakMultiplier = ${c.attackDamageVsWeakMultiplier}`);
if (c.poisonHits != null) fields.push(`poisonHits = ${c.poisonHits}`);
if (c.attackDamageVsWeakMultiplier != null) fields.push(`attackDamageVsWeakMultiplier = ${luaNum(c.attackDamageVsWeakMultiplier)}`);
if (c.poisonHits != null) fields.push(`poisonHits = ${luaNum(c.poisonHits)}`);
if (c.poisonRandomTargets === true) fields.push('poisonRandomTargets = true');
if (c.poisonIfTargetPoisoned === true) fields.push('poisonIfTargetPoisoned = true');
if (c.xDamagePerEnergy != null) fields.push(`xDamagePerEnergy = ${c.xDamagePerEnergy}`);
if (c.xWeakPerEnergy != null) fields.push(`xWeakPerEnergy = ${c.xWeakPerEnergy}`);
if (c.nextTurnBlock != null) fields.push(`nextTurnBlock = ${c.nextTurnBlock}`);
if (c.nextTurnDraw != null) fields.push(`nextTurnDraw = ${c.nextTurnDraw}`);
if (c.xDamagePerEnergy != null) fields.push(`xDamagePerEnergy = ${luaNum(c.xDamagePerEnergy)}`);
if (c.xWeakPerEnergy != null) fields.push(`xWeakPerEnergy = ${luaNum(c.xWeakPerEnergy)}`);
if (c.nextTurnBlock != null) fields.push(`nextTurnBlock = ${luaNum(c.nextTurnBlock)}`);
if (c.nextTurnDraw != null) fields.push(`nextTurnDraw = ${luaNum(c.nextTurnDraw)}`);
if (c.nextTurnKeepBlock === true) fields.push('nextTurnKeepBlock = true');
if (c.nextTurnAttackMultiplier != null) fields.push(`nextTurnAttackMultiplier = ${c.nextTurnAttackMultiplier}`);
if (c.nextTurnCopies != null) fields.push(`nextTurnCopies = ${c.nextTurnCopies}`);
if (c.nextTurnAttackMultiplier != null) fields.push(`nextTurnAttackMultiplier = ${luaNum(c.nextTurnAttackMultiplier)}`);
if (c.nextTurnCopies != null) fields.push(`nextTurnCopies = ${luaNum(c.nextTurnCopies)}`);
if (c.nextTurnSelectHandCard === true) fields.push('nextTurnSelectHandCard = true');
if (c.nextTurnSelectPrompt != null) fields.push(`nextTurnSelectPrompt = ${luaStr(c.nextTurnSelectPrompt)}`);
if (c.nextSkillRepeatCount != null) fields.push(`nextSkillRepeatCount = ${c.nextSkillRepeatCount}`);
if (c.nextSkillRepeatCount != null) fields.push(`nextSkillRepeatCount = ${luaNum(c.nextSkillRepeatCount)}`);
if (c.nextSkillCostZero === true) fields.push('nextSkillCostZero = true');
if (c.skillCostReductionThisTurn != null) fields.push(`skillCostReductionThisTurn = ${c.skillCostReductionThisTurn}`);
if (c.skillCostReductionThisTurn != null) fields.push(`skillCostReductionThisTurn = ${luaNum(c.skillCostReductionThisTurn)}`);
if (c.skillSlyOnPlay === true) fields.push('skillSlyOnPlay = true');
if (c.turnHandSlyCount != null) fields.push(`turnHandSlyCount = ${c.turnHandSlyCount}`);
if (c.combatCostReductionOnPlay != null) fields.push(`combatCostReductionOnPlay = ${c.combatCostReductionOnPlay}`);
if (c.turnHandSlyCount != null) fields.push(`turnHandSlyCount = ${luaNum(c.turnHandSlyCount)}`);
if (c.combatCostReductionOnPlay != null) fields.push(`combatCostReductionOnPlay = ${luaNum(c.combatCostReductionOnPlay)}`);
if (c.randomTargetEachHit === true) fields.push('randomTargetEachHit = true');
if (c.repeatOnKill === true) fields.push('repeatOnKill = true');
if (c.affectsAllEnemies === true) fields.push('affectsAllEnemies = true');
if (c.removeEnemyBlock === true) fields.push('removeEnemyBlock = true');
if (c.removeEnemyArtifact === true) fields.push('removeEnemyArtifact = true');
if (c.enemyStrengthLossThisTurn != null) fields.push(`enemyStrengthLossThisTurn = ${c.enemyStrengthLossThisTurn}`);
if (c.extraPoisonTicks != null) fields.push(`extraPoisonTicks = ${c.extraPoisonTicks}`);
if (c.poisonApplicationBurstEvery != null) fields.push(`poisonApplicationBurstEvery = ${c.poisonApplicationBurstEvery}`);
if (c.poisonApplicationBurstDamage != null) fields.push(`poisonApplicationBurstDamage = ${c.poisonApplicationBurstDamage}`);
if (c.enemyStrengthLossThisTurn != null) fields.push(`enemyStrengthLossThisTurn = ${luaNum(c.enemyStrengthLossThisTurn)}`);
if (c.extraPoisonTicks != null) fields.push(`extraPoisonTicks = ${luaNum(c.extraPoisonTicks)}`);
if (c.poisonApplicationBurstEvery != null) fields.push(`poisonApplicationBurstEvery = ${luaNum(c.poisonApplicationBurstEvery)}`);
if (c.poisonApplicationBurstDamage != null) fields.push(`poisonApplicationBurstDamage = ${luaNum(c.poisonApplicationBurstDamage)}`);
if (c.innate === true) fields.push('innate = true');
if (c.playableWhenDrawPileEmpty === true) fields.push('playableWhenDrawPileEmpty = true');
if (c.sly === true) fields.push('sly = true');
@@ -353,7 +359,7 @@ function luaCardsTable(cards) {
if (c.unplayable === true) fields.push('unplayable = true');
if (c.curse === true) fields.push('curse = true');
if (c.token === true) fields.push('token = true');
if (c.endTurnDamage != null) fields.push(`endTurnDamage = ${c.endTurnDamage}`);
if (c.endTurnDamage != null) fields.push(`endTurnDamage = ${luaNum(c.endTurnDamage)}`);
if (c.fx != null) fields.push(`fx = ${luaStr(c.fx)}`);
if (c.image != null) fields.push(`image = ${luaStr(c.image)}`);
return `\t${id} = { ${fields.join(', ')} },`;