Merge origin/main (#73 도적 카드 아이콘 + in-combat card picker) into feature/maker-ui-edit

#73이 우리 분기(#72) 이후 main에 머지돼 충돌. 해결:
- 소스(boot·deckturn·deckview·gen-slaydeck·data/cards·legacy/hud/deckall): 자동머지로 통합
  (우리 부트폴링/버튼수정/슬롯추종 + #73 thief 아이콘/card-picker 공존).
- 산출물 ui/DefaultGroup.ui: 우리것(메이커 저작 6 UIGroup) 유지(#73의 옛 단일그룹 생성본 폐기).
- 산출물 SlayDeckController.codeblock: 머지된 소스로 재생성(양쪽 기능 모두 반영).
- card-picker reconcile: #73 새 코드의 옛 경로(/ui/DefaultGroup/DeckAllHud)를
  reconnect-ui-paths로 DeckUIGroup으로 remap + 120카드 ButtonComponent 런타임 부착 wrap.
- 검증: cbgap GAP 0, OpenDebugCardPicker/OnAllDeckCardButton 보존, .ui churn 0, JS 41/41.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 22:33:37 +09:00
7 changed files with 312 additions and 98 deletions

View File

@@ -29,10 +29,24 @@ if lp ~= nil then
end
_InputService:ConnectEvent(KeyDownEvent, function(e)
if e.key == KeyboardKey.LeftControl then
self.DebugCtrlDown = true
local lp2 = _UserService.LocalPlayer
if lp2 ~= nil and lp2.CurrentMapName == "${LOBBY_MAP}" and self.RunActive ~= true then
self:PlayerAttackMotion()
end
elseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then
self.DebugShiftDown = true
elseif e.key == KeyboardKey.C then
if self.DebugCtrlDown == true and self.DebugShiftDown == true then
self:OpenDebugCardPicker()
end
end
end)
_InputService:ConnectEvent(KeyUpEvent, function(e)
if e.key == KeyboardKey.LeftControl then
self.DebugCtrlDown = false
elseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then
self.DebugShiftDown = false
end
end)`),
method('ReqLoadAscension', `local ds = _DataStorageService:GetUserDataStorage(userId)

View File

@@ -67,6 +67,13 @@ if allDeckClose ~= nil and (allDeckClose.ButtonComponent ~= nil or allDeckClose:
self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
end
self:BindClassDeckTabs()
for i = 1, 120 do
local allCard = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. tostring(i))
if allCard ~= nil and (allCard.ButtonComponent ~= nil or allCard:AddComponent("ButtonComponent") ~= nil) then
local slot = i
allCard:ConnectEvent(ButtonClickEvent, function() self:OnAllDeckCardButton(slot) end)
end
end
for i = 1, 10 do
local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i))
if cardEntity ~= nil and cardEntity.UITouchReceiveComponent ~= nil then

View File

@@ -94,12 +94,31 @@ if mageTab ~= nil and (mageTab.ButtonComponent ~= nil or mageTab:AddComponent("B
end`),
method('OpenClassDeck', `self.CodexMode = false
self.ClassDeckMode = true
self.DebugCardPickerMode = false
self.DeckAllOpen = true
self:SetClassDeckTab(className)
local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud")
if hud ~= nil then
hud.Enable = true
end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'className' }]),
method('OpenDebugCardPicker', `if self.RunActive ~= true or self.CombatOver == true or self.Hand == nil then
self:Toast("전투 중에만 테스트 카드를 추가할 수 있습니다")
return
end
local className = self.SelectedClass
if className ~= "warrior" and className ~= "magician" and className ~= "bandit" then
className = "bandit"
end
self.CodexMode = false
self.ClassDeckMode = true
self.DebugCardPickerMode = true
self.DeckAllOpen = true
self:SetClassDeckTab(className)
local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud")
if hud ~= nil then
hud.Enable = true
end
self:Toast("테스트 카드 추가 모드")`),
method('SetClassDeckTab', `if self.ClassDeckMode ~= true then
return
end
@@ -171,6 +190,7 @@ end
self.DeckInspectKind = ""
self.ClassDeckMode = false
self.ClassDeckClass = ""
self.DebugCardPickerMode = false
self:RenderClassDeckTabs()
self.DeckAllOpen = true
self:RenderAllDeck()
@@ -189,6 +209,7 @@ if self.ClassDeckMode == true then
self.ClassDeckTitle = ""
self.ClassDeckClass = ""
end
self.DebugCardPickerMode = false
self:RenderClassDeckTabs()
if self.CodexMode == true then
self.CodexMode = false
@@ -199,6 +220,9 @@ local title = "모든 덱"
if self.ClassDeckMode == true then
pile = self.ClassDeckCards or {}
title = self.ClassDeckTitle
if self.DebugCardPickerMode == true then
title = title .. " - 테스트 카드 추가"
end
elseif self.CodexMode == true then
pile = self.CodexCards or {}
title = "카드 도감"
@@ -226,4 +250,21 @@ end`),
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
]),
method('OnAllDeckCardButton', `if self.DebugCardPickerMode ~= true then
return
end
if self.ClassDeckCards == nil then
return
end
local cardId = self.ClassDeckCards[slot]
if cardId == nil or self.Cards == nil or self.Cards[cardId] == nil then
return
end
self:AddCardsToHand(cardId, 1)
local c = self.Cards[cardId]
local name = cardId
if c.name ~= nil then name = c.name end
self:Toast("테스트 카드 추가: " .. name)`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
]),
];

View File

@@ -62,6 +62,9 @@ function writeCodeblocks() {
prop('boolean', 'CodexMode', 'false'),
prop('any', 'CodexCards'),
prop('boolean', 'ClassDeckMode', 'false'),
prop('boolean', 'DebugCardPickerMode', 'false'),
prop('boolean', 'DebugCtrlDown', 'false'),
prop('boolean', 'DebugShiftDown', 'false'),
prop('any', 'ClassDeckCards'),
prop('string', 'ClassDeckTitle', '""'),
prop('string', 'ClassDeckClass', '""'),

View File

@@ -116,11 +116,12 @@ export function buildDeckAll() {
path: cardPath,
modelId: 'uisprite',
entryId: 'UISprite',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent',
displayOrder: i,
components: [
transform({ parentW: 980, parentH: 620, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: ALL_DECK_CARD_W, y: ALL_DECK_CARD_H }, pos: { x: 0, y: 0 } }),
sprite({ dataId: CARDFRAMES.frames.warrior.normal, color: WHITE, type: 0 }),
sprite({ dataId: CARDFRAMES.frames.warrior.normal, color: WHITE, type: 0, raycast: true }),
button(),
],
});
card.jsonString.enable = false;