feat: 도적 공용 효과 정리

This commit is contained in:
2026-06-22 21:59:28 +09:00
parent 4f9be00ff2
commit a3d5174b34
11 changed files with 805 additions and 239 deletions

View File

@@ -59,6 +59,9 @@ end
if c.kind == "Skill" and self.SkillCostReductionThisTurn ~= nil and self.SkillCostReductionThisTurn > 0 then
cost = math.max(0, cost - self.SkillCostReductionThisTurn)
end
if self.CombatCardCostReduction ~= nil and self.CombatCardCostReduction[cardId] ~= nil then
cost = math.max(0, cost - self.CombatCardCostReduction[cardId])
end
if c.kind == "Skill" and self.NextSkillRepeatCount ~= nil and self.NextSkillRepeatCount > 0 then
skillRepeat = self.NextSkillRepeatCount
end
@@ -103,6 +106,12 @@ end
if self.ActiveKillReward ~= nil and self.ActiveKillReward <= 0 then
self.ActiveKillReward = 0
end
if c.combatCostReductionOnPlay ~= nil and c.combatCostReductionOnPlay > 0 then
if self.CombatCardCostReduction == nil then
self.CombatCardCostReduction = {}
end
self.CombatCardCostReduction[cardId] = (self.CombatCardCostReduction[cardId] or 0) + c.combatCostReductionOnPlay
end
table.remove(self.Hand, slot)
if c.exhaust == true then
if self.ExhaustPile == nil then self.ExhaustPile = {} end
@@ -283,7 +292,7 @@ m.hp = m.hp - dmg
if dmg > 0 then
local poison = self:AddPowerFieldTotal("attackPoison")
if poison ~= nil and poison > 0 then
m.poison = (m.poison or 0) + poison
self:ApplyPoisonToMonster(m, poison)
end
end
self:MonsterHitMotion(m.slot)
@@ -345,6 +354,62 @@ end
return killed`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
], 0, 'boolean'),
method('ApplyPoisonToMonster', `if target == nil or target.alive ~= true or amount == nil or amount <= 0 then
return
end
if target.artifact ~= nil and target.artifact > 0 then
target.artifact = target.artifact - 1
return
end
target.poison = (target.poison or 0) + amount
self.PoisonApplicationsThisCombat = (self.PoisonApplicationsThisCombat or 0) + 1
local burstEvery = self:AddPowerFieldTotal("poisonApplicationBurstEvery")
local burstDamage = self:AddPowerFieldTotal("poisonApplicationBurstDamage")
if burstEvery ~= nil and burstEvery > 0 and burstDamage ~= nil and burstDamage > 0 then
if (self.PoisonApplicationsThisCombat % burstEvery) == 0 then
self:DealDamageToAllMonsters(burstDamage)
end
end`, [
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'target' },
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
]),
method('DealDamageToAllMonsters', `if self.Monsters == nil then
return false
end
local killCount = 0
for i = 1, #self.Monsters do
local m = self.Monsters[i]
if m ~= nil and m.alive == true then
local dmg = amount
if m.vuln > 0 then
dmg = math.floor(dmg * 1.5)
end
if m.block > 0 then
local absorbed = math.min(m.block, dmg)
m.block = m.block - absorbed
dmg = dmg - absorbed
end
m.hp = m.hp - dmg
if dmg > 0 then
self.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + dmg
end
self:ShowDmgPop(i, dmg)
self:MonsterHitMotion(i)
if m.hp <= 0 then
m.hp = 0
self:KillMonster(m.slot)
killCount = killCount + 1
end
end
end
if killCount > 0 and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then
self.BonusRewardScreens = (self.BonusRewardScreens or 0) + (killCount * self.ActiveKillReward)
end
self:RenderCombat()
self:CheckCombatEnd()
return killCount > 0`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
], 0, 'boolean'),
method('PlayAttackFx', `local m = self.Monsters[targetIndex]
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
self:DealDamageToTarget(damage, pierce)
@@ -426,7 +491,7 @@ _TimerService:SetTimerOnce(function()
if dmg > 0 then
local poison = self:AddPowerFieldTotal("attackPoison")
if poison ~= nil and poison > 0 then
m.poison = (m.poison or 0) + poison
self:ApplyPoisonToMonster(m, poison)
end
end
self:ShowDmgPop(i, dmg)
@@ -518,18 +583,25 @@ local m = self.Monsters[idx]
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(idx)
self:SetEntityEnabled(base .. "/ActFrame", true)
_TimerService:SetTimerOnce(function()
if m.poison ~= nil and m.poison > 0 then
m.hp = m.hp - m.poison
self:ShowDmgPop(idx, m.poison)
self:MonsterHitMotion(idx)
m.poison = m.poison - 1
if m.hp <= 0 then
m.hp = 0
self:KillMonster(m.slot)
self:RenderCombat()
self:SetEntityEnabled(base .. "/ActFrame", false)
_TimerService:SetTimerOnce(function() self:EnemyActStep(idx + 1) end, 0.15)
return
local poisonTicks = 1
local bonusTicks = self:AddPowerFieldTotal("extraPoisonTicks")
if bonusTicks ~= nil and bonusTicks > 0 then
poisonTicks = poisonTicks + bonusTicks
end
for pt = 1, poisonTicks do
if m.poison ~= nil and m.poison > 0 then
m.hp = m.hp - m.poison
self:ShowDmgPop(idx, m.poison)
self:MonsterHitMotion(idx)
m.poison = m.poison - 1
if m.hp <= 0 then
m.hp = 0
self:KillMonster(m.slot)
self:RenderCombat()
self:SetEntityEnabled(base .. "/ActFrame", false)
_TimerService:SetTimerOnce(function() self:EnemyActStep(idx + 1) end, 0.15)
return
end
end
end
m.block = 0
@@ -538,6 +610,10 @@ _TimerService:SetTimerOnce(function()
if intent.kind == "Attack" then
self:MonsterLunge(idx)
local atk = intent.value + m.str
if self.EnemyStrengthLossThisTurn ~= nil and self.EnemyStrengthLossThisTurn > 0 then
atk = atk - self.EnemyStrengthLossThisTurn
if atk < 0 then atk = 0 end
end
if m.weak > 0 then
atk = math.floor(atk * 0.75)
end

View File

@@ -228,6 +228,8 @@ self.RetainSelectActive = false
self.ReserveSelectActive = false
self.TurnAttackCardsPlayed = 0
self.TurnDiscardedCards = 0
self.TurnCardsPlayedThisTurn = 0
self.DamageDealtThisTurn = 0
self.NextTurnSelectCopies = 0
self.NextTurnSelectPrompt = ""
self.SkillCostReductionThisTurn = 0
@@ -252,6 +254,9 @@ self.ActiveAttackDamageVsWeakMultiplier = 1
self.DrawDamageThisTurn = 0
self.DrawPoisonThisTurn = 0
self.ShivAoeThisCombat = false
self.SkillSlyOnPlayCards = self.SkillSlyOnPlayCards or {}
self.TurnSkillSlyCards = {}
self.EnemyStrengthLossThisTurn = 0
self.HandCostZeroThisTurn = false
self.DrawDisabledThisTurn = false
local powerTurnDraw = 0
@@ -271,7 +276,7 @@ if self.PlayerPowers ~= 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
self:ApplyPoisonToMonster(tm, pc.value)
end
end
end
@@ -448,6 +453,7 @@ 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)
self:RenderPiles()
self.TurnSkillSlyCards = {}
self:EnemyTurn()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'retainSlot' }]),
method('DrawCards', `local drawnSlots = {}
local drawnCards = {}

View File

@@ -311,6 +311,9 @@ end
if c.damagePerCardDrawnThisCombat ~= nil then
base2 = base2 + (self.CardsDrawnThisCombat or 0) * c.damagePerCardDrawnThisCombat
end
if c.class == "Attack" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then
base2 = base2 + c.firstCardDamageBonus
end
if c.class == "shiv" then
if self:HasPowerField("shivDamageBonus") == true then
base2 = base2 + self:AddPowerFieldTotal("shivDamageBonus")
@@ -411,6 +414,33 @@ end
if c.shivAoe == true and c.kind ~= "Power" then
self.ShivAoeThisCombat = true
end
if c.skillSlyOnPlay == true and c.kind == "Skill" then
if self.SkillSlyOnPlayCards == nil then
self.SkillSlyOnPlayCards = {}
end
self.SkillSlyOnPlayCards[cardId] = true
end
if c.turnHandSlyCount ~= nil and c.turnHandSlyCount > 0 then
if self.TurnSkillSlyCards == nil then
self.TurnSkillSlyCards = {}
end
local picked = 0
if self.Hand ~= nil then
for i = 1, #self.Hand do
local hid = self.Hand[i]
if hid ~= nil and hid ~= cardId then
local hc = self.Cards[hid]
if hc ~= nil and hc.kind == "Skill" and self.TurnSkillSlyCards[hid] ~= true and self.SkillSlyOnPlayCards[hid] ~= true and hc.sly ~= true then
self.TurnSkillSlyCards[hid] = true
picked = picked + 1
if picked >= c.turnHandSlyCount then
break
end
end
end
end
end
end
local xEnergy = energySpent or 0
local weakAmount = c.weak or 0
local vulnAmount = c.vuln or 0
@@ -448,11 +478,60 @@ if c.kind == "Attack" then
if c.class == "shiv" and self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField("firstShivDamageBonus") == true then
self.ShivFirstDamageBonusUsed = true
end
if useAoe == true then
self:PlayAoeFx(c.fx or c.image, total)
else
self:PlayAttackFx(self.TargetIndex, c.fx or c.image, total, c.pierce == true)
local function countAliveMonsters()
local n = 0
if self.Monsters ~= nil then
for mi = 1, #self.Monsters do
local om = self.Monsters[mi]
if om ~= nil and om.alive == true then n = n + 1 end
end
end
return n
end
local function randomAliveMonsterIndex()
local alive = {}
if self.Monsters ~= nil then
for mi = 1, #self.Monsters do
local om = self.Monsters[mi]
if om ~= nil and om.alive == true then
table.insert(alive, mi)
end
end
end
if #alive <= 0 then
return 0
end
return alive[math.random(1, #alive)]
end
local function resolveAttackRound()
local roundKilled = false
if useAoe == true then
local killed = self:DealDamageToAllMonsters(total)
if killed == true then roundKilled = true end
elseif c.randomTargetEachHit == true then
for h = 1, hitN do
local targetIdx = randomAliveMonsterIndex()
if targetIdx ~= nil and targetIdx > 0 then
local prev = self.TargetIndex
self.TargetIndex = targetIdx
local killed = self:DealDamageToTarget(total / hitN, c.pierce == true)
self.TargetIndex = prev
if killed == true then roundKilled = true end
end
end
else
local killed = self:DealDamageToTarget(total, c.pierce == true)
if killed == true then roundKilled = true end
end
return roundKilled
end
local totalDamage = 0
local roundKilled = false
repeat
roundKilled = resolveAttackRound()
totalDamage = totalDamage + total
until c.repeatOnKill ~= true or roundKilled ~= true or countAliveMonsters() <= 0
self.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + totalDamage
end
if c.block ~= nil then
self:AddCardBlock(c.block)
@@ -490,41 +569,86 @@ end
if c.intangible ~= nil and c.intangible > 0 then
self.PlayerIntangible = (self.PlayerIntangible or 0) + c.intangible
end
self.TurnCardsPlayedThisTurn = (self.TurnCardsPlayedThisTurn or 0) + 1
if c.blockPerDamageDealtThisTurn ~= nil and c.blockPerDamageDealtThisTurn > 0 then
self:AddCardBlock((self.DamageDealtThisTurn or 0) * c.blockPerDamageDealtThisTurn)
end
self:QueueNextTurnEffects(c)
if c.weak ~= nil or c.vuln ~= nil or c.poison ~= nil or c.xWeakPerEnergy ~= nil then
if c.combatCostReductionOnPlay ~= nil and c.combatCostReductionOnPlay > 0 then
if self.CombatCardCostReduction == nil then
self.CombatCardCostReduction = {}
end
self.CombatCardCostReduction[cardId] = (self.CombatCardCostReduction[cardId] or 0) + c.combatCostReductionOnPlay
end
if c.weak ~= nil or c.vuln ~= nil or c.poison ~= nil or c.xWeakPerEnergy ~= nil or c.affectsAllEnemies == true or c.removeEnemyBlock == true or c.removeEnemyArtifact == true or (c.enemyStrengthLossThisTurn ~= nil and c.enemyStrengthLossThisTurn > 0) then
local tm = self.Monsters[self.TargetIndex]
if tm == nil or tm.alive ~= true then
for i = 1, #self.Monsters do
if self.Monsters[i].alive == true then tm = self.Monsters[i]; self.TargetIndex = i; break end
end
end
if tm ~= nil and tm.alive == true then
if weakAmount ~= nil and weakAmount > 0 then tm.weak = tm.weak + weakAmount end
if poisonAmount ~= nil and poisonAmount > 0 then
local poisonHits = c.poisonHits or 1
for pi = 1, poisonHits do
local target = tm
if c.poisonRandomTargets == true and self.Monsters ~= nil then
local alive = {}
for mi = 1, #self.Monsters do
local om = self.Monsters[mi]
if om ~= nil and om.alive == true then
table.insert(alive, om)
end
end
if #alive > 0 then
target = alive[math.random(#alive)]
end
end
if target ~= nil and target.alive == true then
target.poison = (target.poison or 0) + poisonAmount
end
local targets = {}
if c.affectsAllEnemies == true and self.Monsters ~= nil then
for mi = 1, #self.Monsters do
local om = self.Monsters[mi]
if om ~= nil and om.alive == true then
table.insert(targets, om)
end
end
if vulnAmount ~= nil and vulnAmount > 0 then
tm.vuln = tm.vuln + vulnAmount
if self:HasRelic("championBelt") then
tm.weak = tm.weak + 1
elseif tm ~= nil and tm.alive == true then
table.insert(targets, tm)
end
if c.enemyStrengthLossThisTurn ~= nil and c.enemyStrengthLossThisTurn > 0 then
self.EnemyStrengthLossThisTurn = (self.EnemyStrengthLossThisTurn or 0) + c.enemyStrengthLossThisTurn
end
for ti = 1, #targets do
local target = targets[ti]
if target ~= nil and target.alive == true then
if c.removeEnemyBlock == true then
target.block = 0
end
if c.removeEnemyArtifact == true then
target.artifact = 0
end
if weakAmount ~= nil and weakAmount > 0 then
if target.artifact ~= nil and target.artifact > 0 then
target.artifact = target.artifact - 1
else
target.weak = target.weak + weakAmount
end
end
if poisonAmount ~= nil and poisonAmount > 0 then
if c.poisonIfTargetPoisoned ~= true or (target.poison ~= nil and target.poison > 0) then
local poisonHits = c.poisonHits or 1
for pi = 1, poisonHits do
local target2 = target
if c.poisonRandomTargets == true and self.Monsters ~= nil then
local alive = {}
for mi = 1, #self.Monsters do
local om = self.Monsters[mi]
if om ~= nil and om.alive == true then
table.insert(alive, om)
end
end
if #alive > 0 then
target2 = alive[math.random(#alive)]
end
end
if target2 ~= nil and target2.alive == true then
self:ApplyPoisonToMonster(target2, poisonAmount)
end
end
end
end
if vulnAmount ~= nil and vulnAmount > 0 then
if target.artifact ~= nil and target.artifact > 0 then
target.artifact = target.artifact - 1
else
target.vuln = target.vuln + vulnAmount
if self:HasRelic("championBelt") then
target.weak = target.weak + 1
end
end
end
end
end
@@ -573,10 +697,11 @@ if (drawDamage ~= nil and drawDamage > 0) or (drawPoison ~= nil and drawPoison >
dmg = dmg - absorbed
end
if drawPoison ~= nil and drawPoison > 0 then
m2.poison = (m2.poison or 0) + drawPoison
self:ApplyPoisonToMonster(m2, drawPoison)
end
if dmg > 0 then
m2.hp = m2.hp - dmg
self.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + dmg
end
self:ShowDmgPop(mi, dmg)
self:MonsterHitMotion(mi)
@@ -599,9 +724,16 @@ end`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'energySpent' },
]),
method('TriggerSly', `local c = self.Cards[cardId]
if c == nil or c.sly ~= true then
if c == nil then
return
end
if c.sly ~= true then
local onPlay = self.SkillSlyOnPlayCards ~= nil and self.SkillSlyOnPlayCards[cardId] == true
local tempSly = self.TurnSkillSlyCards ~= nil and self.TurnSkillSlyCards[cardId] == true
if onPlay ~= true and tempSly ~= true then
return
end
end
self:Toast("교활 발동: " .. c.name)
self:ResolveCardEffects(cardId, 0, c, true, 0)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' }]),
method('DiscardHandCard', `if self.Hand == nil then

View File

@@ -74,11 +74,16 @@ self.DrawDisabledThisTurn = false
self.NextSkillCostZero = false
self.NextSkillRepeatCount = 0
self.SkillCostReductionThisTurn = 0
self.CombatCardCostReduction = {}
self.SkillSlyOnPlayCards = {}
self.TurnSkillSlyCards = {}
self.ShivFirstDamageBonusUsed = false
self.ActiveAttackDamageVsWeakMultiplier = 1
self.DrawDamageThisTurn = 0
self.DrawPoisonThisTurn = 0
self.ShivAoeThisCombat = false
self.PoisonApplicationsThisCombat = 0
self.EnemyStrengthLossThisTurn = 0
self.PlayerStr = 0
self.PlayerDex = 0
self.PlayerThorns = 0
@@ -91,6 +96,8 @@ self.PlayerPowers = {}
self.FightAttackCount = 0
self.TurnAttackCardsPlayed = 0
self.TurnDiscardedCards = 0
self.TurnCardsPlayedThisTurn = 0
self.DamageDealtThisTurn = 0
self.DmgPopSeq = 0
self.FirstHpLossDone = false
self.ClayBlockNext = 0
@@ -233,7 +240,7 @@ for i = 1, n do
local startIdx = 1
if #intents > 0 then startIdx = math.random(1, #intents) end
self.Monsters[i] = { entity = item.entity, enemyId = item.enemyId, name = e.name,
hp = maxHp, maxHp = maxHp, block = 0, str = 0, weak = 0, vuln = 0, poison = 0,
hp = maxHp, maxHp = maxHp, block = 0, str = e.str or 0, weak = 0, vuln = 0, poison = 0, artifact = e.artifact or 0,
hitClip = hitClip, standClip = standClip, motionBusy = false,
intents = intents, intentIdx = startIdx, alive = true, slot = i }
self:ReviveMonsterEntity(item.entity)