Compare commits
2 Commits
5da6e8f3aa
...
codex/band
| Author | SHA1 | Date | |
|---|---|---|---|
| acf295d56c | |||
| b2bf1bf4dd |
File diff suppressed because one or more lines are too long
@@ -803,8 +803,8 @@
|
||||
"class": "bandit",
|
||||
"rarity": "unique",
|
||||
"desc": "카드를 1장 뽑습니다. 뽑은 카드가 스킬 카드라면, 방어도를 3 얻습니다.",
|
||||
"block": 3,
|
||||
"draw": 1,
|
||||
"drawSkillBlock": 3,
|
||||
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
|
||||
},
|
||||
"Acrobatics": {
|
||||
@@ -985,8 +985,8 @@
|
||||
"rarity": "unique",
|
||||
"desc": "내 턴 시작 시, 모든 적에게 중독을 2 부여합니다.",
|
||||
"poison": 2,
|
||||
"powerEffect": "strengthPerTurn",
|
||||
"value": 1,
|
||||
"powerEffect": "poisonPerTurn",
|
||||
"value": 2,
|
||||
"image": "19361e72087946b1888684185b40d935"
|
||||
},
|
||||
"Accuracy": {
|
||||
@@ -1019,9 +1019,8 @@
|
||||
"rarity": "unique",
|
||||
"desc": "내 턴 동안 카드를 뽑을 때마다, 모든 적에게 피해를 2 줍니다.",
|
||||
"aoe": true,
|
||||
"powerEffect": "strengthPerTurn",
|
||||
"value": 1,
|
||||
"damage": 2,
|
||||
"powerEffect": "damagePerTurn",
|
||||
"value": 2,
|
||||
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
|
||||
},
|
||||
"GrandFinale": {
|
||||
@@ -1179,8 +1178,8 @@
|
||||
"class": "bandit",
|
||||
"rarity": "legend",
|
||||
"desc": "이번 턴 동안 더 이상 카드를 뽑을 수 없습니다. 이번 턴 동안 손에 있는 모든 카드를 비용 없이 사용할 수 있습니다.",
|
||||
"powerEffect": "energyPerTurn",
|
||||
"value": 1,
|
||||
"handCostZeroThisTurn": true,
|
||||
"drawDisabledThisTurn": true,
|
||||
"image": "91a2d1c16cb041549adbf1a0d7b1f37f"
|
||||
},
|
||||
"Nightmare": {
|
||||
|
||||
22
docs/draw-skill-block.md
Normal file
22
docs/draw-skill-block.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 드로우 연동 효과
|
||||
|
||||
드로우 결과를 받아 후속 효과를 처리하는 공용 패턴을 정리합니다.
|
||||
|
||||
## 현재 구현
|
||||
|
||||
- `draw`: 카드를 뽑음
|
||||
- `drawUntilHandSize`: 손패가 지정 수치가 될 때까지 뽑음
|
||||
- `drawSkillBlock`: 이번 카드로 뽑힌 카드 중 스킬 카드마다 방어도를 얻음
|
||||
|
||||
## 동작 방식
|
||||
|
||||
- 드로우 함수는 이번에 뽑힌 카드 ID 목록을 반환합니다.
|
||||
- 카드 효과는 그 목록을 보고 조건을 판정합니다.
|
||||
- 그래서 `EscapePlan` 같은 카드뿐 아니라, 나중에 같은 규칙이 필요한 카드에도 같은 필드를 붙이면 됩니다.
|
||||
|
||||
## 예시
|
||||
|
||||
- `EscapePlan`
|
||||
- `draw = 1`
|
||||
- `drawSkillBlock = 3`
|
||||
|
||||
@@ -94,7 +94,8 @@ export function chooseAction(hand, cards, energy, ctx = {}) {
|
||||
const card = cards[x.id];
|
||||
if (!card || card.unplayable || !canPlayCardNow(card, ctx)) return false;
|
||||
let effectiveCost = card.cost || 0;
|
||||
if (card.kind === 'Skill') {
|
||||
if (ctx.handCostZeroThisTurn === true) effectiveCost = 0;
|
||||
else if (card.kind === 'Skill') {
|
||||
if (ctx.nextSkillCostZero === true) effectiveCost = 0;
|
||||
else effectiveCost = Math.max(0, effectiveCost - (ctx.skillCostReductionThisTurn || 0));
|
||||
}
|
||||
@@ -105,7 +106,8 @@ export function chooseAction(hand, cards, energy, ctx = {}) {
|
||||
const skills = entries.filter((x) => cards[x.id].kind === 'Skill');
|
||||
const effectiveCost = (card) => {
|
||||
let cost = card.cost || 0;
|
||||
if (card.kind === 'Skill') {
|
||||
if (ctx.handCostZeroThisTurn === true) cost = 0;
|
||||
else if (card.kind === 'Skill') {
|
||||
if (ctx.nextSkillCostZero === true) cost = 0;
|
||||
else cost = Math.max(0, cost - (ctx.skillCostReductionThisTurn || 0));
|
||||
}
|
||||
@@ -146,6 +148,8 @@ export function simulateCombat(data, rng, stats) {
|
||||
let pHp = PLAYER_HP, pBlock = 0;
|
||||
let pStr = 0, pDex = 0, pThorns = 0, pWeak = 0, pVuln = 0;
|
||||
let blockGainMultiplier = 1;
|
||||
let handCostZeroThisTurn = false;
|
||||
let drawDisabledThisTurn = false;
|
||||
let nextSkillCostZero = false;
|
||||
let skillCostReductionThisTurn = 0;
|
||||
let nextTurnBlock = 0, nextTurnDraw = 0, nextTurnKeepBlock = false;
|
||||
@@ -161,16 +165,20 @@ export function simulateCombat(data, rng, stats) {
|
||||
let turns = 0;
|
||||
|
||||
function draw(n) {
|
||||
const drawn = [];
|
||||
if (drawDisabledThisTurn === true) return drawn;
|
||||
for (let k = 0; k < n; k++) {
|
||||
if (drawPile.length === 0) { drawPile = shuffle(discard, rng); discard = []; }
|
||||
if (drawPile.length === 0) break;
|
||||
const card = drawPile.pop();
|
||||
drawn.push(card);
|
||||
// 손패 10장 상한 — 초과 드로는 자동 버림 (Lua DrawCards 동기화)
|
||||
if (hand.length >= 10) {
|
||||
discard.push(card);
|
||||
triggerSly(card);
|
||||
} else hand.push(card);
|
||||
}
|
||||
return drawn;
|
||||
}
|
||||
function addCardsToHand(id, n) {
|
||||
for (let k = 0; k < n; k++) {
|
||||
@@ -267,6 +275,8 @@ export function simulateCombat(data, rng, stats) {
|
||||
if (c.blockGainMultiplier && c.blockGainMultiplier > 0) blockGainMultiplier *= c.blockGainMultiplier;
|
||||
if (c.nextSkillCostZero === true) nextSkillCostZero = true;
|
||||
if (c.skillCostReductionThisTurn && c.skillCostReductionThisTurn > 0) skillCostReductionThisTurn += c.skillCostReductionThisTurn;
|
||||
if (c.handCostZeroThisTurn === true) handCostZeroThisTurn = true;
|
||||
if (c.drawDisabledThisTurn === true) drawDisabledThisTurn = true;
|
||||
if (c.kind === 'Attack') {
|
||||
if (alive.length && c.damage) {
|
||||
const baseDamage = attackBaseForCard(id, c);
|
||||
@@ -318,10 +328,16 @@ export function simulateCombat(data, rng, stats) {
|
||||
if (c.heal) pHp = Math.min(pHp + c.heal, PLAYER_HP);
|
||||
if (c.gainEnergy) energy += c.gainEnergy;
|
||||
queueNextTurnEffects(c);
|
||||
if (c.draw) draw(c.draw);
|
||||
let drawnCards = [];
|
||||
if (c.draw) drawnCards = drawnCards.concat(draw(c.draw));
|
||||
if (c.drawUntilHandSize) {
|
||||
const need = c.drawUntilHandSize - Math.max(0, hand.length - 1);
|
||||
if (need > 0) draw(need);
|
||||
if (need > 0) drawnCards = drawnCards.concat(draw(need));
|
||||
}
|
||||
if (c.drawSkillBlock && c.drawSkillBlock > 0) {
|
||||
for (const drawnId of drawnCards) {
|
||||
if (cards[drawnId]?.kind === 'Skill') blockGained += addBlock(c.drawSkillBlock);
|
||||
}
|
||||
}
|
||||
if (c.addShiv && !c.discard && c.discardAll !== true) addCardsToHand('Shiv', c.addShiv);
|
||||
if (recordStats && stats) stats[id] = bump(stats[id], costSpent, dmg, blockGained);
|
||||
@@ -356,6 +372,8 @@ export function simulateCombat(data, rng, stats) {
|
||||
turnAttackCardsPlayed = 0;
|
||||
turnDiscardedCards = 0;
|
||||
blockGainMultiplier = 1;
|
||||
handCostZeroThisTurn = false;
|
||||
drawDisabledThisTurn = false;
|
||||
skillCostReductionThisTurn = 0;
|
||||
// 파워 발동 — Lua StartPlayerTurn 동기화 (블록 리셋 후 strength/energy/block 파워)
|
||||
if (nextTurnKeepBlock === true) nextTurnKeepBlock = false;
|
||||
@@ -371,6 +389,16 @@ export function simulateCombat(data, rng, stats) {
|
||||
if (pc.powerEffect === 'strengthPerTurn') pStr += pc.value;
|
||||
else if (pc.powerEffect === 'energyPerTurn') energyBonus += pc.value;
|
||||
else if (pc.powerEffect === 'blockPerTurn') pBlock += pc.value;
|
||||
else if (pc.powerEffect === 'poisonPerTurn') {
|
||||
for (const m of mob) if (m.alive) m.poison += pc.value;
|
||||
} else if (pc.powerEffect === 'damagePerTurn') {
|
||||
for (const m of mob) {
|
||||
if (!m.alive) continue;
|
||||
const r = applyDamage(m.hp, m.block, pc.value || 0);
|
||||
m.hp = r.hp; m.block = r.block;
|
||||
if (m.hp <= 0) m.alive = false;
|
||||
}
|
||||
}
|
||||
if (pc.turnStartShiv) addCardsToHand('Shiv', pc.turnStartShiv);
|
||||
if (pc.turnStartDraw) powerTurnDraw += pc.turnStartDraw;
|
||||
if (pc.turnStartDiscard) powerTurnDiscard += pc.turnStartDiscard;
|
||||
@@ -388,12 +416,12 @@ export function simulateCombat(data, rng, stats) {
|
||||
while (true) {
|
||||
const alive = aliveList();
|
||||
if (alive.length === 0) break;
|
||||
const idx = chooseAction(hand, cards, energy, { drawPileCount: drawPile.length, nextSkillCostZero, skillCostReductionThisTurn });
|
||||
const idx = chooseAction(hand, cards, energy, { drawPileCount: drawPile.length, nextSkillCostZero, skillCostReductionThisTurn, handCostZeroThisTurn });
|
||||
if (idx < 0) break;
|
||||
const id = hand[idx], c = cards[id];
|
||||
const skillFree = c.kind === 'Skill' && nextSkillCostZero === true;
|
||||
const baseCost = c.cost || 0;
|
||||
const cost = skillFree ? 0 : (c.kind === 'Skill' ? Math.max(0, baseCost - skillCostReductionThisTurn) : baseCost);
|
||||
const cost = handCostZeroThisTurn === true ? 0 : (skillFree ? 0 : (c.kind === 'Skill' ? Math.max(0, baseCost - skillCostReductionThisTurn) : baseCost));
|
||||
energy -= cost;
|
||||
resolveCardEffects(id, c, cost);
|
||||
if (c.kind === 'Attack') turnAttackCardsPlayed++;
|
||||
|
||||
@@ -720,3 +720,60 @@ test("chooseAction: skillCostReductionThisTurn allows discounted skills", () =>
|
||||
assert.equal(chooseAction(["Guard"], cards, 1, { skillCostReductionThisTurn: 1 }), 0);
|
||||
assert.equal(chooseAction(["Guard"], cards, 1, {}), -1);
|
||||
});
|
||||
|
||||
test("chooseAction: handCostZeroThisTurn lets expensive cards be played", () => {
|
||||
const cards = {
|
||||
Burst: { name: "Burst", cost: 3, kind: "Skill", block: 8 },
|
||||
};
|
||||
assert.equal(chooseAction(["Burst"], cards, 0, { handCostZeroThisTurn: true }), 0);
|
||||
assert.equal(chooseAction(["Burst"], cards, 0, {}), -1);
|
||||
});
|
||||
|
||||
test("simulateCombat: drawSkillBlock grants block for each drawn skill", () => {
|
||||
const data = {
|
||||
cards: {
|
||||
Escape: { name: "EscapePlan", cost: 0, kind: "Skill", draw: 1, drawSkillBlock: 3, innate: true, exhaust: true },
|
||||
Filler1: { name: "Filler1", cost: 99, kind: "Skill", block: 0 },
|
||||
Filler2: { name: "Filler2", cost: 99, kind: "Skill", block: 0 },
|
||||
Filler3: { name: "Filler3", cost: 99, kind: "Skill", block: 0 },
|
||||
Filler4: { name: "Filler4", cost: 99, kind: "Skill", block: 0 },
|
||||
Filler5: { name: "Filler5", cost: 99, kind: "Skill", block: 0 },
|
||||
},
|
||||
starterDeck: ["Escape", "Filler1", "Filler2", "Filler3", "Filler4", "Filler5"],
|
||||
monsters: [{ name: "Dummy", maxHp: 9999, intents: [{ kind: "Attack", value: 0 }] }],
|
||||
};
|
||||
const stats = {};
|
||||
const r = simulateCombat(data, () => 0.999999, stats);
|
||||
assert.equal(r.draw, true);
|
||||
assert.equal(stats.Escape.block, 3);
|
||||
});
|
||||
|
||||
test("simulateCombat: poisonPerTurn powers poison all enemies at turn start", () => {
|
||||
const data = {
|
||||
cards: {
|
||||
Fumes: { name: "NoxiousFumes", cost: 1, kind: "Power", powerEffect: "poisonPerTurn", value: 2 },
|
||||
},
|
||||
starterDeck: ["Fumes"],
|
||||
monsters: [
|
||||
{ name: "DummyA", maxHp: 2, intents: [{ kind: "Attack", value: 0 }] },
|
||||
{ name: "DummyB", maxHp: 2, intents: [{ kind: "Attack", value: 0 }] },
|
||||
],
|
||||
};
|
||||
const r = simulateCombat(data, () => 0.999999);
|
||||
assert.equal(r.win, true);
|
||||
});
|
||||
|
||||
test("simulateCombat: damagePerTurn powers damage all enemies at turn start", () => {
|
||||
const data = {
|
||||
cards: {
|
||||
Speed: { name: "Speedster", cost: 2, kind: "Power", powerEffect: "damagePerTurn", value: 2 },
|
||||
},
|
||||
starterDeck: ["Speed"],
|
||||
monsters: [
|
||||
{ name: "DummyA", maxHp: 2, intents: [{ kind: "Attack", value: 0 }] },
|
||||
{ name: "DummyB", maxHp: 2, intents: [{ kind: "Attack", value: 0 }] },
|
||||
],
|
||||
};
|
||||
const r = simulateCombat(data, () => 0.999999);
|
||||
assert.equal(r.win, true);
|
||||
});
|
||||
|
||||
@@ -46,6 +46,9 @@ if self:CanPlayCardNow(c) ~= true then
|
||||
end
|
||||
local cost = c.cost or 0
|
||||
local skillFree = false
|
||||
if self.HandCostZeroThisTurn == true then
|
||||
\tcost = 0
|
||||
end
|
||||
if c.kind == "Skill" and self.NextSkillCostZero == true then
|
||||
cost = 0
|
||||
skillFree = true
|
||||
|
||||
@@ -246,6 +246,8 @@ if self.ClayBlockNext > 0 then
|
||||
end
|
||||
self.TurnAttackMultiplier = self.NextTurnAttackMultiplier or 1
|
||||
self.NextTurnAttackMultiplier = 1
|
||||
self.HandCostZeroThisTurn = false
|
||||
self.DrawDisabledThisTurn = false
|
||||
local powerTurnDraw = 0
|
||||
local powerTurnDiscard = 0
|
||||
if self.PlayerPowers ~= nil then
|
||||
@@ -258,6 +260,19 @@ if self.PlayerPowers ~= nil then
|
||||
self.Energy = self.Energy + pc.value
|
||||
elseif pc.powerEffect == "blockPerTurn" then
|
||||
self.PlayerBlock = self.PlayerBlock + pc.value
|
||||
elseif pc.powerEffect == "poisonPerTurn" then
|
||||
if self.Monsters ~= nil then
|
||||
for j = 1, #self.Monsters do
|
||||
local tm = self.Monsters[j]
|
||||
if tm ~= nil and tm.alive == true then
|
||||
tm.poison = (tm.poison or 0) + pc.value
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif pc.powerEffect == "damagePerTurn" then
|
||||
if self.Monsters ~= nil then
|
||||
self:PlayAoeFx(pc.fx or pc.image, pc.value or 0)
|
||||
end
|
||||
end
|
||||
if pc.turnStartShiv ~= nil then
|
||||
self:AddCardsToHand("Shiv", pc.turnStartShiv)
|
||||
@@ -415,8 +430,12 @@ if self.PlayerVuln > 0 then self.PlayerVuln = self.PlayerVuln - 1 end
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
self:EnemyTurn()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'retainSlot' }]),
|
||||
method('DrawCards', `local drawnSlots = {}
|
||||
method('DrawCards', `local drawnSlots = {}
|
||||
local drawnCards = {}
|
||||
local drewAny = false
|
||||
if self.DrawDisabledThisTurn == true then
|
||||
\treturn drawnCards
|
||||
end
|
||||
for i = 1, amount do
|
||||
\tif #self.DrawPile <= 0 then
|
||||
\t\tself:RecycleDiscardIntoDraw()
|
||||
@@ -425,6 +444,7 @@ for i = 1, amount do
|
||||
\t\tbreak
|
||||
\tend
|
||||
\tlocal cardId = table.remove(self.DrawPile)
|
||||
\ttable.insert(drawnCards, cardId)
|
||||
\tif #self.Hand >= 10 then
|
||||
\t\ttable.insert(self.DiscardPile, cardId)
|
||||
\t\tself:TriggerSly(cardId)
|
||||
@@ -444,10 +464,11 @@ if animate == true and #drawnSlots > 0 then
|
||||
\t\tlocal slot = drawnSlots[i]
|
||||
\t\tself:AnimateCardFrom(slot, drawStart, Vector2(self:GetHandSlotX(slot), 0), 0.08 + i * 0.045)
|
||||
\tend
|
||||
return drawnCards
|
||||
end`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'animate' },
|
||||
]),
|
||||
], 0, 'any'),
|
||||
method('AddCardsToHand', `if self.Hand == nil then
|
||||
self.Hand = {}
|
||||
end
|
||||
|
||||
@@ -60,7 +60,7 @@ if e ~= nil and e.SpriteGUIRendererComponent ~= nil then
|
||||
end
|
||||
self:SetText(base .. "/Cost", string.format("%d", c.cost))
|
||||
self:SetText(base .. "/Name", c.name)
|
||||
self:SetText(base .. "/Desc", c.desc)
|
||||
self:SetText(base .. "/Desc", self:FormatCardDescription(c.desc))
|
||||
local art = _EntityService:GetEntityByPath(base .. "/Art")
|
||||
if art ~= nil then
|
||||
if c.image ~= nil and c.image ~= "" then
|
||||
@@ -382,6 +382,12 @@ end
|
||||
if c.skillCostReductionThisTurn ~= nil and c.skillCostReductionThisTurn > 0 then
|
||||
self.SkillCostReductionThisTurn = (self.SkillCostReductionThisTurn or 0) + c.skillCostReductionThisTurn
|
||||
end
|
||||
if c.handCostZeroThisTurn == true then
|
||||
self.HandCostZeroThisTurn = true
|
||||
end
|
||||
if c.drawDisabledThisTurn == true then
|
||||
self.DrawDisabledThisTurn = true
|
||||
end
|
||||
if c.kind == "Attack" then
|
||||
if c.damage ~= nil then
|
||||
self:PlayerAttackMotion()
|
||||
@@ -459,8 +465,9 @@ if c.weak ~= nil or c.vuln ~= nil or c.poison ~= nil then
|
||||
end
|
||||
end
|
||||
end
|
||||
local drawnCards = {}
|
||||
if c.draw ~= nil then
|
||||
self:DrawCards(c.draw, true)
|
||||
drawnCards = self:DrawCards(c.draw, true) or {}
|
||||
end
|
||||
if c.drawUntilHandSize ~= nil and c.drawUntilHandSize > 0 then
|
||||
local currentHand = 0
|
||||
@@ -472,7 +479,18 @@ if c.drawUntilHandSize ~= nil and c.drawUntilHandSize > 0 then
|
||||
end
|
||||
local need = c.drawUntilHandSize - currentHand
|
||||
if need > 0 then
|
||||
self:DrawCards(need, true)
|
||||
local moreDrawnCards = self:DrawCards(need, true) or {}
|
||||
for i = 1, #moreDrawnCards do
|
||||
table.insert(drawnCards, moreDrawnCards[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
if c.drawSkillBlock ~= nil and c.drawSkillBlock > 0 then
|
||||
for i = 1, #drawnCards do
|
||||
local drawnCard = self.Cards[drawnCards[i]]
|
||||
if drawnCard ~= nil and drawnCard.kind == "Skill" then
|
||||
self:AddCardBlock(c.drawSkillBlock)
|
||||
end
|
||||
end
|
||||
end
|
||||
if c.addShiv ~= nil and c.discard == nil and c.discardAll ~= true then
|
||||
|
||||
@@ -68,6 +68,8 @@ self.MaxEnergy = 3
|
||||
self.Turn = 0
|
||||
self.PlayerBlock = 0
|
||||
self.BlockGainMultiplier = 1
|
||||
self.HandCostZeroThisTurn = false
|
||||
self.DrawDisabledThisTurn = false
|
||||
self.NextSkillCostZero = false
|
||||
self.SkillCostReductionThisTurn = 0
|
||||
self.PlayerStr = 0
|
||||
|
||||
@@ -3,6 +3,47 @@ import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_
|
||||
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||
|
||||
export const tooltipMethods = [
|
||||
method('FormatCardDescription', `if desc == nil or desc == "" then
|
||||
return ""
|
||||
end
|
||||
local function replacePlain(text, needle, replacement)
|
||||
local out = ""
|
||||
local pos = 1
|
||||
while true do
|
||||
local s, e = string.find(text, needle, pos, true)
|
||||
if s == nil then
|
||||
out = out .. string.sub(text, pos)
|
||||
break
|
||||
end
|
||||
out = out .. string.sub(text, pos, s - 1) .. replacement
|
||||
pos = e + 1
|
||||
end
|
||||
return out
|
||||
end
|
||||
local terms = {
|
||||
"교활",
|
||||
"보존",
|
||||
"민첩",
|
||||
"가시",
|
||||
"소멸",
|
||||
"선천성",
|
||||
"취약",
|
||||
"약화",
|
||||
"독",
|
||||
"광역",
|
||||
"관통",
|
||||
"방어도",
|
||||
"힘",
|
||||
"스킬",
|
||||
"공격",
|
||||
"파워",
|
||||
}
|
||||
local out = desc
|
||||
for i = 1, #terms do
|
||||
local term = terms[i]
|
||||
out = replacePlain(out, term, "<color=#70D6FF>" .. term .. "</color>")
|
||||
end
|
||||
return out`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'desc' }], 0, 'string'),
|
||||
method('BuildCardKeywordTooltip', `if c == nil then
|
||||
return ""
|
||||
end
|
||||
|
||||
@@ -162,6 +162,8 @@ function luaCardsTable(cards) {
|
||||
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.damagePerTurn != null) fields.push(`damagePerTurn = ${c.damagePerTurn}`);
|
||||
if (c.poisonPerTurn != null) fields.push(`poisonPerTurn = ${c.poisonPerTurn}`);
|
||||
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}`);
|
||||
@@ -182,6 +184,7 @@ function luaCardsTable(cards) {
|
||||
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.heal != null) fields.push(`heal = ${c.heal}`);
|
||||
if (c.gainEnergy != null) fields.push(`gainEnergy = ${c.gainEnergy}`);
|
||||
if (c.poison != null) fields.push(`poison = ${c.poison}`);
|
||||
@@ -192,6 +195,8 @@ function luaCardsTable(cards) {
|
||||
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.handCostZeroThisTurn === true) fields.push('handCostZeroThisTurn = true');
|
||||
if (c.drawDisabledThisTurn === true) fields.push('drawDisabledThisTurn = true');
|
||||
if (c.addShivPerDiscard === true) fields.push('addShivPerDiscard = true');
|
||||
if (c.nextTurnBlock != null) fields.push(`nextTurnBlock = ${c.nextTurnBlock}`);
|
||||
if (c.nextTurnDraw != null) fields.push(`nextTurnDraw = ${c.nextTurnDraw}`);
|
||||
|
||||
Reference in New Issue
Block a user