From f88e6ffeebd6525fe7cf1beddd179d0020abb9c8 Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 11 Jun 2026 08:31:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(combat-feel):=20=EC=A0=81=20=EA=B0=9C?= =?UTF-8?q?=EB=B3=84=20=EC=B0=A8=EB=A1=80=20=EC=8B=9C=ED=80=80=EC=8A=A4=20?= =?UTF-8?q?(ActFrame=C2=B7EnemyActStep)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- tools/deck/gen-slaydeck.mjs | 70 +++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/tools/deck/gen-slaydeck.mjs b/tools/deck/gen-slaydeck.mjs index e753f6b..2632b78 100644 --- a/tools/deck/gen-slaydeck.mjs +++ b/tools/deck/gen-slaydeck.mjs @@ -939,6 +939,17 @@ function upsertUi() { }); targetFrame.jsonString.enable = false; combat.push(targetFrame); + const actFrame = entity({ + id: guid('cmb', 240 + i), path: `${base}/ActFrame`, modelId: 'uisprite', entryId: 'UISprite', + componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent', + displayOrder: 0, + components: [ + transform({ parentW: SLOT_W, parentH: SLOT_H, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: SLOT_W + 16, y: SLOT_H + 12 }, pos: { x: 0, y: 0 } }), + sprite({ color: { r: 0.95, g: 0.3, b: 0.25, a: 0.3 }, type: 1 }), + ], + }); + actFrame.jsonString.enable = false; + combat.push(actFrame); combat.push(entity({ id: guid('cmb', 60 + i), path: `${base}/Name`, modelId: 'uitext', entryId: 'UIText', componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.TextComponent', @@ -2179,12 +2190,7 @@ end self.Hand = {} self:RenderHand(false) self:RenderPiles() -self:EnemyTurn() -self:CheckCombatEnd() -if self.CombatOver == true then - return -end -_TimerService:SetTimerOnce(function() self:StartPlayerTurn() end, 0.45)`), +self:EnemyTurn()`), method('DrawCards', `for i = 1, amount do \tif #self.DrawPile <= 0 then \t\tself:RecycleDiscardIntoDraw() @@ -2578,25 +2584,45 @@ self.PlayerHp = self.PlayerHp - dmg if self.PlayerHp < 0 then self.PlayerHp = 0 end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]), - method('EnemyTurn', `for i = 1, #self.Monsters do - local m = self.Monsters[i] - if m.alive == true then - m.block = 0 - local intent = m.intents[m.intentIdx] - if intent ~= nil then - if intent.kind == "Attack" then - self:DealDamageToPlayer(intent.value) - elseif intent.kind == "Defend" then - m.block = m.block + intent.value - end - end - m.intentIdx = m.intentIdx + 1 - if m.intentIdx > #m.intents then - m.intentIdx = 1 + method('EnemyTurn', `self.TurnBusy = true +self:EnemyActStep(1)`), + method('EnemyActStep', `local idx = 0 +for i = fromIndex, #self.Monsters do + if self.Monsters[i].alive == true then idx = i; break end +end +if idx == 0 or self.PlayerHp <= 0 then + self:FinishEnemyTurn() + return +end +local m = self.Monsters[idx] +local base = "/ui/DefaultGroup/CombatHud/MonsterSlot" .. tostring(idx) +self:SetEntityEnabled(base .. "/ActFrame", true) +_TimerService:SetTimerOnce(function() + m.block = 0 + local intent = m.intents[m.intentIdx] + if intent ~= nil then + if intent.kind == "Attack" then + local before = self.PlayerHp + self:DealDamageToPlayer(intent.value) + self:ShowPlayerDmgPop(before - self.PlayerHp) + elseif intent.kind == "Defend" then + m.block = m.block + intent.value end end + m.intentIdx = m.intentIdx + 1 + if m.intentIdx > #m.intents then + m.intentIdx = 1 + end + self:RenderCombat() + self:SetEntityEnabled(base .. "/ActFrame", false) + _TimerService:SetTimerOnce(function() self:EnemyActStep(idx + 1) end, 0.15) +end, 0.45)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'fromIndex' }]), + method('FinishEnemyTurn', `self.TurnBusy = false +self:CheckCombatEnd() +if self.CombatOver == true then + return end -self:RenderCombat()`), +_TimerService:SetTimerOnce(function() self:StartPlayerTurn() end, 0.45)`), method('CheckCombatEnd', `local anyAlive = false for i = 1, #self.Monsters do if self.Monsters[i].alive == true then anyAlive = true; break end