feat(combat-feel): 공격 이펙트 후 지연 데미지 (SkillFx·FxBusy)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 08:25:05 +09:00
parent c80020a464
commit 4b7ad753a4

View File

@@ -1100,6 +1100,18 @@ function upsertUi() {
text({ value: '모든덱보기', fontSize: 18, bold: true, color: GOLD, alignment: 0 }),
],
}));
const skillFx = entity({
id: guid('cmb', 230), path: '/ui/DefaultGroup/CombatHud/SkillFx',
modelId: 'uisprite', entryId: 'UISprite',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent',
displayOrder: 30,
components: [
transform({ parentW: 1920, parentH: 1080, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: 110, y: 110 }, pos: { x: 0, y: 0 } }),
sprite({ color: { r: 1, g: 1, b: 1, a: 1 }, type: 0, raycast: false }),
],
});
skillFx.jsonString.enable = false;
combat.push(skillFx);
const result = entity({
id: guid('cmb', 2),
path: '/ui/DefaultGroup/CombatHud/Result',
@@ -2134,7 +2146,7 @@ self.PlayerBlock = 0
self:DrawCards(5)
self:RenderHand(true)
self:RenderCombat()`),
method('EndPlayerTurn', `if self.CombatOver == true then
method('EndPlayerTurn', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
for i = 1, #self.Hand do
@@ -2358,7 +2370,7 @@ end, 1 / 60)`, [
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'toPos' },
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'duration' },
]),
method('PlayCard', `if self.CombatOver == true then
method('PlayCard', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
if self.Hand == nil then
@@ -2379,7 +2391,7 @@ end
self.Energy = self.Energy - c.cost
if c.kind == "Attack" then
if c.damage ~= nil then
self:DealDamageToTarget(c.damage)
self:PlayAttackFx(self.TargetIndex, c.image, c.damage)
end
self:ApplyRelics("cardPlayed")
elseif c.kind == "Skill" then
@@ -2487,6 +2499,38 @@ if m.hp <= 0 then
m.hp = 0
self:KillMonster(m.slot)
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
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)
self:RenderCombat()
self:CheckCombatEnd()
return
end
self.FxBusy = true
local fx = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/SkillFx")
if fx ~= nil then
if fx.SpriteGUIRendererComponent ~= nil and image ~= nil and image ~= "" then
fx.SpriteGUIRendererComponent.ImageRUID = image
end
if fx.UITransformComponent ~= nil and m.entity.TransformComponent ~= nil then
local wp = m.entity.TransformComponent.WorldPosition
local sp = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 0.7))
fx.UITransformComponent.anchoredPosition = _UILogic:ScreenToUIPosition(sp)
end
fx.Enable = true
end
_TimerService:SetTimerOnce(function()
if fx ~= nil then fx.Enable = false end
self.FxBusy = false
self:DealDamageToTarget(damage)
self:ShowDmgPop(targetIndex, damage)
self:RenderCombat()
self:CheckCombatEnd()
end, 0.35)`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'targetIndex' },
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'image' },
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'damage' },
]),
method('KillMonster', `local m = self.Monsters[slot]
if m == nil then
return