From a5c7d96770b26be600f0ced8fd1733a8b3887e39 Mon Sep 17 00:00:00 2001 From: gahusb Date: Wed, 10 Jun 2026 01:17:32 +0900 Subject: [PATCH] =?UTF-8?q?feat(combat):=20=EC=8A=B9=EB=A6=AC=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4(=EC=A0=84=EC=B2=B4=20=EC=B2=98=EC=B9=98)=C2=B7?= =?UTF-8?q?=EB=AA=AC=EC=8A=A4=ED=84=B0=20=EC=8A=AC=EB=A1=AF=20=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=C2=B7HP=EB=B0=94=C2=B7=ED=83=80=EA=B2=9F=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD?= 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 | 66 ++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/tools/deck/gen-slaydeck.mjs b/tools/deck/gen-slaydeck.mjs index 8aeb738..a5ed3f1 100644 --- a/tools/deck/gen-slaydeck.mjs +++ b/tools/deck/gen-slaydeck.mjs @@ -1206,6 +1206,12 @@ end local restLeave = _EntityService:GetEntityByPath("/ui/DefaultGroup/RestHud/Leave") if restLeave ~= nil and restLeave.ButtonComponent ~= nil then restLeave:ConnectEvent(ButtonClickEvent, function() self:LeaveNode() end) +end +for i = 1, ${MAX_MONSTERS} do + local ms = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/MonsterSlot" .. tostring(i)) + if ms ~= nil and ms.ButtonComponent ~= nil then + ms:ConnectEvent(ButtonClickEvent, function() self:SetTarget(i) end) + end end`), method('StartPlayerTurn', `self.Turn = self.Turn + 1 self.Energy = self.MaxEnergy @@ -1420,7 +1426,11 @@ end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], N end end self:RenderCombat()`), - method('CheckCombatEnd', `if self.EnemyHp <= 0 then + method('CheckCombatEnd', `local anyAlive = false +for i = 1, #self.Monsters do + if self.Monsters[i].alive == true then anyAlive = true; break end +end +if anyAlive == false then self.CombatOver = true self.Gold = self.Gold + ${GOLD_PER_WIN} self:ApplyRelics("combatReward") @@ -1453,22 +1463,54 @@ local entity = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/Result if entity ~= nil then entity.Enable = true end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'text' }]), - method('RenderCombat', `self:SetText("/ui/DefaultGroup/CombatHud/EnemyName", self.EnemyName) -self:SetText("/ui/DefaultGroup/CombatHud/EnemyHp", "HP " .. string.format("%d", self.EnemyHp) .. "/" .. string.format("%d", self.EnemyMaxHp)) -self:SetText("/ui/DefaultGroup/CombatHud/EnemyBlock", "방어 " .. string.format("%d", self.EnemyBlock)) -local intent = self.EnemyIntents[self.EnemyIntentIndex] -local intentText = "" -if intent ~= nil then - if intent.kind == "Attack" then - intentText = "의도: 공격 " .. tostring(intent.value) - elseif intent.kind == "Defend" then - intentText = "의도: 방어 " .. tostring(intent.value) + method('RenderCombat', `for i = 1, ${MAX_MONSTERS} do + local base = "/ui/DefaultGroup/CombatHud/MonsterSlot" .. tostring(i) + local m = self.Monsters[i] + if m ~= nil and m.alive == true then + self:SetEntityEnabled(base, true) + self:SetText(base .. "/Name", m.name) + self:SetText(base .. "/Hp", string.format("%d", m.hp) .. "/" .. string.format("%d", m.maxHp)) + local intent = m.intents[m.intentIdx] + local t = "" + if intent ~= nil then + if intent.kind == "Attack" then t = "공격 " .. tostring(intent.value) + elseif intent.kind == "Defend" then t = "방어 " .. tostring(intent.value) end + end + if i == self.TargetIndex then t = "[타겟] " .. t end + self:SetText(base .. "/Intent", t) + self:SetHpBar(base .. "/HpBarFill", m.hp, m.maxHp) + else + self:SetEntityEnabled(base, false) end end -self:SetText("/ui/DefaultGroup/CombatHud/EnemyIntent", intentText) self:SetText("/ui/DefaultGroup/CombatHud/PlayerHp", "HP " .. string.format("%d", self.PlayerHp) .. "/" .. string.format("%d", self.PlayerMaxHp)) self:SetText("/ui/DefaultGroup/CombatHud/PlayerBlock", "방어 " .. string.format("%d", self.PlayerBlock)) self:RenderRun()`), + method('SetHpBar', `local e = _EntityService:GetEntityByPath(path) +if e == nil or e.UITransformComponent == nil then + return +end +local ratio = 0 +if maxHp > 0 then ratio = hp / maxHp end +if ratio < 0 then ratio = 0 end +local w = 120 * ratio +e.UITransformComponent.RectSize = Vector2(w, 14)`, [ + { Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }, + { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hp' }, + { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' }, + ]), + method('PositionMonsterSlot', `local sp = self.SlotPos +if sp == nil or sp[slot] == nil then + return +end +local e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/MonsterSlot" .. tostring(slot)) +if e ~= nil and e.UITransformComponent ~= nil then + e.UITransformComponent.anchoredPosition = Vector2(sp[slot].x, sp[slot].y) +end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]), + method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then + self.TargetIndex = slot + self:RenderCombat() +end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]), method('RenderRun', `self:SetText("/ui/DefaultGroup/CombatHud/Floor", "막 " .. string.format("%d", self.Floor) .. "/" .. string.format("%d", self.RunLength)) self:SetText("/ui/DefaultGroup/CombatHud/Gold", "골드 " .. string.format("%d", self.Gold))`), method('OfferReward', `local pool = {}