diff --git a/RootDesk/MyDesk/SlayDeckController.codeblock b/RootDesk/MyDesk/SlayDeckController.codeblock index 38e6e82..18d3778 100644 --- a/RootDesk/MyDesk/SlayDeckController.codeblock +++ b/RootDesk/MyDesk/SlayDeckController.codeblock @@ -84,6 +84,13 @@ "SyncDirection": 0, "Attributes": [], "Name": "EndTurnHandler" + }, + { + "Type": "any", + "DefaultValue": "nil", + "SyncDirection": 0, + "Attributes": [], + "Name": "Cards" } ], "Methods": [ @@ -111,7 +118,7 @@ "Name": null }, "Arguments": [], - "Code": "self.MaxEnergy = 3\nself.Turn = 0\nself.DiscardPile = {}\nself.Hand = {}\nself.DrawPile = { \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Defend\", \"Defend\", \"Defend\", \"Defend\", \"Bash\" }\nself:Shuffle(self.DrawPile)\nself:BindButtons()\nself:StartPlayerTurn()", + "Code": "self.MaxEnergy = 3\nself.Turn = 0\nself.DiscardPile = {}\nself.Hand = {}\nself.Cards = {\n\tStrike = { name = \"타격\", cost = 1, desc = \"피해 6\", kind = \"Attack\" },\n\tDefend = { name = \"방어\", cost = 1, desc = \"방어도 5\", kind = \"Skill\" },\n\tBash = { name = \"강타\", cost = 2, desc = \"피해 10\", kind = \"Attack\" },\n}\nself.DrawPile = { \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Defend\", \"Defend\", \"Defend\", \"Defend\", \"Bash\" }\nself:Shuffle(self.DrawPile)\nself:BindButtons()\nself:StartPlayerTurn()", "Scope": 2, "ExecSpace": 6, "Attributes": [], @@ -149,7 +156,7 @@ "Name": null }, "Arguments": [], - "Code": "local buttonEntity = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/DeckHud/EndTurnButton\")\nif buttonEntity == nil or buttonEntity.ButtonComponent == nil then\n\treturn\nend\nif self.EndTurnHandler ~= nil then\n\tbuttonEntity:DisconnectEvent(ButtonClickEvent, self.EndTurnHandler)\n\tself.EndTurnHandler = nil\nend\nself.EndTurnHandler = buttonEntity:ConnectEvent(ButtonClickEvent, self.EndPlayerTurn)", + "Code": "local endTurn = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/DeckHud/EndTurnButton\")\nif endTurn ~= nil and endTurn.ButtonComponent ~= nil then\n\tif self.EndTurnHandler ~= nil then\n\t\tendTurn:DisconnectEvent(ButtonClickEvent, self.EndTurnHandler)\n\t\tself.EndTurnHandler = nil\n\tend\n\tself.EndTurnHandler = endTurn:ConnectEvent(ButtonClickEvent, function() self:EndPlayerTurn() end)\nend\nfor i = 1, 5 do\n\tlocal cardEntity = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(i))\n\tif cardEntity ~= nil and cardEntity.ButtonComponent ~= nil then\n\t\tcardEntity:ConnectEvent(ButtonClickEvent, function() self:PlayCard(i) end)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], @@ -285,7 +292,7 @@ "Name": "cardId" } ], - "Code": "local name = cardId\nlocal cost = 0\nlocal desc = \"\"\nlocal kind = \"Skill\"\nif cardId == \"Strike\" then\n\tname = \"타격\"\n\tcost = 1\n\tdesc = \"피해 6\"\n\tkind = \"Attack\"\nelseif cardId == \"Defend\" then\n\tname = \"방어\"\n\tcost = 1\n\tdesc = \"방어도 5\"\n\tkind = \"Skill\"\nelseif cardId == \"Bash\" then\n\tname = \"강타\"\n\tcost = 2\n\tdesc = \"피해 10\"\n\tkind = \"Attack\"\nend\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Cost\", tostring(cost))\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Name\", name)\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Desc\", desc)\nlocal cardEntity = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot))\nif cardEntity ~= nil and cardEntity.SpriteGUIRendererComponent ~= nil then\n\tlocal ok = false\n\tlocal color = nil\n\tif kind == \"Attack\" then\n\t\tok, color = pcall(function() return Color(0.86, 0.42, 0.38, 1) end)\n\telseif kind == \"Skill\" then\n\t\tok, color = pcall(function() return Color(0.42, 0.55, 0.85, 1) end)\n\telse\n\t\tok, color = pcall(function() return Color(0.46, 0.68, 0.52, 1) end)\n\tend\n\tif ok == true and color ~= nil then\n\t\tcardEntity.SpriteGUIRendererComponent.Color = color\n\tend\nend", + "Code": "local c = self.Cards[cardId]\nif c == nil then\n\tc = { name = cardId, cost = 0, desc = \"\", kind = \"Skill\" }\nend\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Cost\", tostring(c.cost))\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Name\", c.name)\nself:SetText(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot) .. \"/Desc\", c.desc)\nlocal cardEntity = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/CardHand/Card\" .. tostring(slot))\nif cardEntity ~= nil and cardEntity.SpriteGUIRendererComponent ~= nil then\n\tif c.kind == \"Attack\" then\n\t\tcardEntity.SpriteGUIRendererComponent.Color = Color(0.86, 0.42, 0.38, 1)\n\telseif c.kind == \"Skill\" then\n\t\tcardEntity.SpriteGUIRendererComponent.Color = Color(0.42, 0.55, 0.85, 1)\n\telse\n\t\tcardEntity.SpriteGUIRendererComponent.Color = Color(0.46, 0.68, 0.52, 1)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], @@ -364,6 +371,52 @@ "ExecSpace": 6, "Attributes": [], "Name": "AnimateCardFrom" + }, + { + "Return": { + "Type": "void", + "DefaultValue": null, + "SyncDirection": 0, + "Attributes": [], + "Name": null + }, + "Arguments": [ + { + "Type": "number", + "DefaultValue": null, + "SyncDirection": 0, + "Attributes": [], + "Name": "slot" + } + ], + "Code": "if self.Hand == nil then\n\treturn\nend\nlocal cardId = self.Hand[slot]\nif cardId == nil then\n\treturn\nend\nlocal c = self.Cards[cardId]\nif c == nil then\n\treturn\nend\nif self.Energy < c.cost then\n\tself:Toast(\"에너지가 부족합니다\")\n\treturn\nend\nself.Energy = self.Energy - c.cost\nself:Toast(c.name .. \" — \" .. c.desc)\ntable.remove(self.Hand, slot)\ntable.insert(self.DiscardPile, cardId)\nself:RenderHand(false)\nself:RenderPiles()", + "Scope": 2, + "ExecSpace": 6, + "Attributes": [], + "Name": "PlayCard" + }, + { + "Return": { + "Type": "void", + "DefaultValue": null, + "SyncDirection": 0, + "Attributes": [], + "Name": null + }, + "Arguments": [ + { + "Type": "string", + "DefaultValue": null, + "SyncDirection": 0, + "Attributes": [], + "Name": "message" + } + ], + "Code": "log(message)", + "Scope": 2, + "ExecSpace": 6, + "Attributes": [], + "Name": "Toast" } ], "EntityEventHandlers": [] diff --git a/docs/superpowers/plans/2026-06-08-deck-controller-fixes.md b/docs/superpowers/plans/2026-06-08-deck-controller-fixes.md new file mode 100644 index 0000000..166a5ff --- /dev/null +++ b/docs/superpowers/plans/2026-06-08-deck-controller-fixes.md @@ -0,0 +1,256 @@ +# 덱 컨트롤러 코드리뷰 수정 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 코드리뷰 6건(①self바인딩 ②Card5통일 ③카드클릭=사용 ④카드데이터단일화 ⑤매직넘버 ⑥pcall)을 `tools/gen-slaydeck.mjs`에서 수정·재생성한다. + +**Architecture:** 모든 산출물(카드 UI·DeckHud·`SlayDeckController.codeblock`·`common.gamelogic`)을 생성하는 `tools/gen-slaydeck.mjs` 단일 소스를 수정하고 재실행한다. DRY는 카드 정의를 codeblock의 `self.Cards` 테이블 프로퍼티로 단일화하고, 카드 클릭은 카드 엔티티에 `ButtonComponent`를 추가한 뒤 `PlayCard(slot)` 메서드를 클로저로 연결해 구현한다. + +**Tech Stack:** Node.js 생성기, MSW codeblock(MapleScript/Lua), msw-maker-mcp(검증). + +--- + +## File Structure +- Modify: `tools/gen-slaydeck.mjs` — 모든 수정의 단일 소스. +- 재생성(출력): `ui/DefaultGroup.ui`, `RootDesk/MyDesk/SlayDeckController.codeblock`, `Global/common.gamelogic`. + +기준: codeblock 메서드는 `method('Name', ``, [args])`로 정의되고 끝에서 전부 `ExecSpace=6`로 설정됨. 카드 엔티티(Card1~5)는 `upsertUi`의 루프가 스타일링함. `button()` 헬퍼 존재. + +--- + +### Task 1: 생성기 수정 (① ③ ④ ⑥ + ⑤ 일부) + +**Files:** Modify `tools/gen-slaydeck.mjs` + +- [ ] **Step 1: 카드에 ButtonComponent + raycast 추가 (③ 클릭 가능)** + +`upsertUi`의 카드 루프에서 `sp.Color = cards[i - 1].tint;` 줄 바로 다음에 아래를 추가: +```js + sp.RaycastTarget = true; + const comps = card.jsonString['@components']; + if (!comps.some((c) => c['@type'] === 'MOD.Core.ButtonComponent')) { + comps.push(button()); + } + if (!card.componentNames.includes('MOD.Core.ButtonComponent')) { + card.componentNames += ',MOD.Core.ButtonComponent'; + } +``` + +- [ ] **Step 2: `Cards` 프로퍼티 추가 (④ 단일화 준비)** + +`writeCodeblocks`의 properties 배열(`prop('any', 'EndTurnHandler')` 가 있는 배열)에 항목 추가: +```js + prop('any', 'Cards'), +``` + +- [ ] **Step 3: StartCombat 메서드 교체 (④ 카드 테이블 정의)** + +`method('StartCombat', ...)` 의 Lua 본문을 아래로 교체: +``` +self.MaxEnergy = 3 +self.Turn = 0 +self.DiscardPile = {} +self.Hand = {} +self.Cards = { + Strike = { name = "타격", cost = 1, desc = "피해 6", kind = "Attack" }, + Defend = { name = "방어", cost = 1, desc = "방어도 5", kind = "Skill" }, + Bash = { name = "강타", cost = 2, desc = "피해 10", kind = "Attack" }, +} +self.DrawPile = { "Strike", "Strike", "Strike", "Strike", "Strike", "Defend", "Defend", "Defend", "Defend", "Bash" } +self:Shuffle(self.DrawPile) +self:BindButtons() +self:StartPlayerTurn() +``` + +- [ ] **Step 4: BindButtons 교체 (① 클로저 + ③ 카드 클릭 바인딩)** + +`method('BindButtons', ...)` 의 Lua 본문을 아래로 교체: +``` +local endTurn = _EntityService:GetEntityByPath("/ui/DefaultGroup/DeckHud/EndTurnButton") +if endTurn ~= nil and endTurn.ButtonComponent ~= nil then + if self.EndTurnHandler ~= nil then + endTurn:DisconnectEvent(ButtonClickEvent, self.EndTurnHandler) + self.EndTurnHandler = nil + end + self.EndTurnHandler = endTurn:ConnectEvent(ButtonClickEvent, function() self:EndPlayerTurn() end) +end +for i = 1, 5 do + local cardEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/CardHand/Card" .. tostring(i)) + if cardEntity ~= nil and cardEntity.ButtonComponent ~= nil then + cardEntity:ConnectEvent(ButtonClickEvent, function() self:PlayCard(i) end) + end +end +``` + +- [ ] **Step 5: ApplyCardVisual 교체 (④ self.Cards 사용 + ⑥ pcall 제거)** + +`method('ApplyCardVisual', ...)` 의 Lua 본문을 아래로 교체(인자 slot, cardId 유지): +``` +local c = self.Cards[cardId] +if c == nil then + c = { name = cardId, cost = 0, desc = "", kind = "Skill" } +end +self:SetText("/ui/DefaultGroup/CardHand/Card" .. tostring(slot) .. "/Cost", tostring(c.cost)) +self:SetText("/ui/DefaultGroup/CardHand/Card" .. tostring(slot) .. "/Name", c.name) +self:SetText("/ui/DefaultGroup/CardHand/Card" .. tostring(slot) .. "/Desc", c.desc) +local cardEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/CardHand/Card" .. tostring(slot)) +if cardEntity ~= nil and cardEntity.SpriteGUIRendererComponent ~= nil then + if c.kind == "Attack" then + cardEntity.SpriteGUIRendererComponent.Color = Color(0.86, 0.42, 0.38, 1) + elseif c.kind == "Skill" then + cardEntity.SpriteGUIRendererComponent.Color = Color(0.42, 0.55, 0.85, 1) + else + cardEntity.SpriteGUIRendererComponent.Color = Color(0.46, 0.68, 0.52, 1) + end +end +``` + +- [ ] **Step 6: PlayCard + Toast 메서드 추가 (③)** + +`method('AnimateCardFrom', ...)` 항목 다음(메서드 배열 안)에 두 메서드를 추가: +```js + method('PlayCard', `if self.Hand == nil then + return +end +local cardId = self.Hand[slot] +if cardId == nil then + return +end +local c = self.Cards[cardId] +if c == nil then + return +end +if self.Energy < c.cost then + self:Toast("에너지가 부족합니다") + return +end +self.Energy = self.Energy - c.cost +self:Toast(c.name .. " — " .. c.desc) +table.remove(self.Hand, slot) +table.insert(self.DiscardPile, cardId) +self:RenderHand(false) +self:RenderPiles()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]), + method('Toast', `log(message)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'message' }]), +``` + +(⑤: 손패/슬롯 수 5는 UI 카드 엔티티가 정확히 5개라 고정값으로 둠 — 별도 상수 불필요. 시작 에너지/MaxEnergy는 이미 프로퍼티.) + +- [ ] **Step 7: 구문 확인 + 커밋** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node --check tools/gen-slaydeck.mjs +git add tools/gen-slaydeck.mjs +git commit -m "덱 컨트롤러 생성기: 핸들러 클로저화·카드데이터 단일화·카드클릭 사용·pcall 제거" +``` +Expected: `node --check` 무출력(exit 0). + +--- + +### Task 2: 재생성 + 데이터 검증 + +**Files:** Modify `ui/DefaultGroup.ui`, `RootDesk/MyDesk/SlayDeckController.codeblock`, `Global/common.gamelogic` + +- [ ] **Step 1: 재생성** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node tools/gen-slaydeck.mjs +``` +Expected: `Slay deck UI and combat codeblocks generated.` + +- [ ] **Step 2: codeblock 검증** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node -e "const j=JSON.parse(require('fs').readFileSync('RootDesk/MyDesk/SlayDeckController.codeblock','utf8'));const ms=j.ContentProto.Json.Methods;const names=ms.map(m=>m.Name);console.log('has PlayCard:',names.includes('PlayCard'));console.log('has Toast:',names.includes('Toast'));const bind=ms.find(m=>m.Name==='BindButtons').Code;console.log('endturn closure:',bind.includes('function() self:EndPlayerTurn() end'));console.log('card click bind:',bind.includes('function() self:PlayCard(i) end'));const av=ms.find(m=>m.Name==='ApplyCardVisual').Code;console.log('no pcall:',!av.includes('pcall'));console.log('uses self.Cards:',av.includes('self.Cards[cardId]'));const sc=ms.find(m=>m.Name==='StartCombat').Code;console.log('Cards table:',sc.includes('self.Cards ='))" +``` +Expected: 모두 `true`. + +- [ ] **Step 3: UI 검증 (카드 버튼 + Card5 통일)** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node -e "const j=JSON.parse(require('fs').readFileSync('ui/DefaultGroup.ui','utf8'));const E=j.ContentProto.Entities;let okBtn=true,okImg=true;for(let i=1;i<=5;i++){const c=E.find(e=>e.path==='/ui/DefaultGroup/CardHand/Card'+i);if(!c){okBtn=false;continue;}if(!(c.componentNames||'').includes('MOD.Core.ButtonComponent'))okBtn=false;const sp=c.jsonString['@components'].find(x=>x['@type']==='MOD.Core.SpriteGUIRendererComponent');if(sp.ImageRUID.DataId!=='')okImg=false;}const c5=E.find(e=>e.path==='/ui/DefaultGroup/CardHand/Card5');const hasDesc=E.some(e=>e.path==='/ui/DefaultGroup/CardHand/Card5/Desc');console.log('all cards have Button:',okBtn);console.log('all cards no image (uniform):',okImg);console.log('Card5 has Desc child:',hasDesc)" +``` +Expected: `all cards have Button: true`, `all cards no image (uniform): true`, `Card5 has Desc child: true`. + +- [ ] **Step 4: JSON 유효성 + 커밋** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node -e "JSON.parse(require('fs').readFileSync('ui/DefaultGroup.ui','utf8'));JSON.parse(require('fs').readFileSync('RootDesk/MyDesk/SlayDeckController.codeblock','utf8'));JSON.parse(require('fs').readFileSync('Global/common.gamelogic','utf8'));console.log('JSON ok')" +git add ui/DefaultGroup.ui RootDesk/MyDesk/SlayDeckController.codeblock Global/common.gamelogic +git commit -m "재생성: 카드 클릭 사용·균일 카드·핸들러 수정 반영" +``` +Expected: `JSON ok`. + +--- + +### Task 3: Maker Play 검증 (컨트롤러) + +**Files:** 없음 + +- [ ] **Step 1: reload**: `maker_refresh_workspace`. +- [ ] **Step 2: 시작 맵 활성화 확인**: `maker_get_current_map`. (어느 맵이든 카드 UI는 전역이라 표시됨) +- [ ] **Step 3: play**: `maker_play`. +- [ ] **Step 4: 클릭 시뮬레이션 + 상태 확인**: `maker_execute_script`(client)로 PlayCard 직접 호출해 동작 확인: + ```lua + local ctrl = _EntityService:GetEntityByPath("/common") + -- 초기 상태 + local c = ctrl.SlayDeckController + log("BEFORE energy="..tostring(c.Energy).." hand="..tostring(#c.Hand).." discard="..tostring(#c.DiscardPile)) + c:PlayCard(1) + log("AFTER energy="..tostring(c.Energy).." hand="..tostring(#c.Hand).." discard="..tostring(#c.DiscardPile)) + ``` + → `maker_logs(normal)`에서 카드 사용 후 energy 감소·hand 감소·discard 증가 확인. (또는 `maker_mouse_input`으로 카드 클릭) +- [ ] **Step 5: screenshot**: `maker_screenshot` → Read로 5장 균일·DeckHud(에너지/덱 카운트) 확인. +- [ ] **Step 6: stop**: `maker_stop`. + +문제 시: 핸들러 self·PlayCard 동작 로그로 진단 후 Task 1 수정·재생성. + +--- + +### Task 4: stash 복구 + 무결성 검증 + +**Files:** `map/map02.map`, `map/map05.map`, `map/map06.map`, `map/map07.map`, `map/map10.map`, `map/map11.map` (복구 대상) + +- [ ] **Step 1: stash 적용** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +git stash list +git stash apply 2>&1 | head -20 +``` +(충돌 시 해당 파일은 main 버전 유지하고 stash 변경만 수동 반영하거나, 무의미하면 제외 — 아래 검증으로 판단) + +- [ ] **Step 2: 무결성 검증 (몬스터/타일셋 유지 확인)** + +```bash +cd "C:/Users/jaeoh/Desktop/workspace/slaymaple" +node -e "const old=['8ef238e0d0ca4bb783aca526cff35d11','6c7130f51a654803a1c39cbe30e2f427','3e76c89ae8e7477ca871f5bbcd6f6f29','6d381bea1bcb4504b518a1fbfa0904ac','c96c11f9a3f845a4b6a27d9ca10ab103'];for(const t of ['02','05','06','07','10','11']){const j=JSON.parse(require('fs').readFileSync('map/map'+t+'.map','utf8'));const E=j.ContentProto.Entities;const ms=E.filter(e=>(e.componentNames||'').includes('script.Monster'));const sprs=ms.map(m=>m.jsonString['@components'].find(c=>c['@type']==='MOD.Core.SpriteRendererComponent').SpriteRUID);const okNoOld=sprs.every(s=>!old.includes(s));const ts=E.find(e=>(e.path||'').endsWith('/TileMap')).jsonString['@components'].find(c=>c['@type']==='MOD.Core.TileMapComponent').TileSetRUID.DataId;console.log('map'+t,'monsters='+ms.length,'noOldSprite='+okNoOld,'tileset='+(ts!=='9dfea3808bbd49a5877d8624df21b1c7'))}" +``` +Expected: 각 맵 `monsters=2`, `noOldSprite=true`, `tileset=true`. (= 몬스터/타일셋 작업 유지됨) + +- [ ] **Step 3: 판정 및 커밋** + +- 무결성 OK → 복구분 커밋: + ```bash + git add map/map02.map map/map05.map map/map06.map map/map07.map map/map10.map map/map11.map + git commit -m "Maker 세션 재저장분(맵 02/05/06/07/10/11) 복구 포함" + git stash drop + ``` +- 무결성 실패(작업 되돌려짐/손상) → 복구 취소하고 사용자에게 보고: + ```bash + git checkout -- map/map02.map map/map05.map map/map06.map map/map07.map map/map10.map map/map11.map + ``` + (stash는 보존) + +--- + +## 검증 요약 +- 생성기 `node --check` 통과 +- codeblock: PlayCard/Toast 존재, EndTurn·카드클릭 클로저, self.Cards 사용, pcall 없음 +- UI: Card1~5 ButtonComponent+raycast, 5장 균일(이미지 없음·Desc 존재) +- Maker Play: PlayCard 호출 시 energy↓·hand↓·discard↑, 5장 균일 렌더 +- stash 복구분 무결성(몬스터2·old미사용·타일셋교체) 검증 후 포함 diff --git a/ui/DefaultGroup.ui b/ui/DefaultGroup.ui index ac62489..eb3652a 100644 --- a/ui/DefaultGroup.ui +++ b/ui/DefaultGroup.ui @@ -1209,7 +1209,7 @@ { "id": "cad00001-0000-4000-8000-000000000001", "path": "/ui/DefaultGroup/CardHand/Card1", - "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent", + "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent", "jsonString": { "name": "Card1", "path": "/ui/DefaultGroup/CardHand/Card1", @@ -1342,6 +1342,53 @@ "RaycastTarget": true, "Type": 1, "Enable": true + }, + { + "@type": "MOD.Core.ButtonComponent", + "Colors": { + "NormalColor": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + }, + "HighlightedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "PressedColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 1 + }, + "SelectedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "DisabledColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 0.5019608 + }, + "ColorMultiplier": 1, + "FadeDuration": 0.1 + }, + "ImageRUIDs": { + "HighlightedSprite": null, + "PressedSprite": null, + "SelectedSprite": null, + "DisabledSprite": null + }, + "KeyCode": 0, + "OverrideSorting": false, + "Transition": 1, + "Enable": true } ], "@version": 1 @@ -1914,7 +1961,7 @@ { "id": "cad00005-0000-4000-8000-000000000005", "path": "/ui/DefaultGroup/CardHand/Card2", - "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent", + "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent", "jsonString": { "name": "Card2", "path": "/ui/DefaultGroup/CardHand/Card2", @@ -2047,6 +2094,53 @@ "RaycastTarget": true, "Type": 1, "Enable": true + }, + { + "@type": "MOD.Core.ButtonComponent", + "Colors": { + "NormalColor": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + }, + "HighlightedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "PressedColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 1 + }, + "SelectedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "DisabledColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 0.5019608 + }, + "ColorMultiplier": 1, + "FadeDuration": 0.1 + }, + "ImageRUIDs": { + "HighlightedSprite": null, + "PressedSprite": null, + "SelectedSprite": null, + "DisabledSprite": null + }, + "KeyCode": 0, + "OverrideSorting": false, + "Transition": 1, + "Enable": true } ], "@version": 1 @@ -2619,7 +2713,7 @@ { "id": "cad00009-0000-4000-8000-000000000009", "path": "/ui/DefaultGroup/CardHand/Card3", - "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent", + "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent", "jsonString": { "name": "Card3", "path": "/ui/DefaultGroup/CardHand/Card3", @@ -2752,6 +2846,53 @@ "RaycastTarget": true, "Type": 1, "Enable": true + }, + { + "@type": "MOD.Core.ButtonComponent", + "Colors": { + "NormalColor": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + }, + "HighlightedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "PressedColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 1 + }, + "SelectedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "DisabledColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 0.5019608 + }, + "ColorMultiplier": 1, + "FadeDuration": 0.1 + }, + "ImageRUIDs": { + "HighlightedSprite": null, + "PressedSprite": null, + "SelectedSprite": null, + "DisabledSprite": null + }, + "KeyCode": 0, + "OverrideSorting": false, + "Transition": 1, + "Enable": true } ], "@version": 1 @@ -3324,7 +3465,7 @@ { "id": "cad0000d-0000-4000-8000-00000000000d", "path": "/ui/DefaultGroup/CardHand/Card4", - "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent", + "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent", "jsonString": { "name": "Card4", "path": "/ui/DefaultGroup/CardHand/Card4", @@ -3457,6 +3598,53 @@ "RaycastTarget": true, "Type": 1, "Enable": true + }, + { + "@type": "MOD.Core.ButtonComponent", + "Colors": { + "NormalColor": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + }, + "HighlightedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "PressedColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 1 + }, + "SelectedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "DisabledColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 0.5019608 + }, + "ColorMultiplier": 1, + "FadeDuration": 0.1 + }, + "ImageRUIDs": { + "HighlightedSprite": null, + "PressedSprite": null, + "SelectedSprite": null, + "DisabledSprite": null + }, + "KeyCode": 0, + "OverrideSorting": false, + "Transition": 1, + "Enable": true } ], "@version": 1 @@ -4029,7 +4217,7 @@ { "id": "cad00011-0000-4000-8000-000000000011", "path": "/ui/DefaultGroup/CardHand/Card5", - "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent", + "componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.ButtonComponent", "jsonString": { "name": "Card5", "path": "/ui/DefaultGroup/CardHand/Card5", @@ -4162,6 +4350,53 @@ "RaycastTarget": true, "Type": 1, "Enable": true + }, + { + "@type": "MOD.Core.ButtonComponent", + "Colors": { + "NormalColor": { + "r": 1, + "g": 1, + "b": 1, + "a": 1 + }, + "HighlightedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "PressedColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 1 + }, + "SelectedColor": { + "r": 0.9607843, + "g": 0.9607843, + "b": 0.9607843, + "a": 1 + }, + "DisabledColor": { + "r": 0.784313738, + "g": 0.784313738, + "b": 0.784313738, + "a": 0.5019608 + }, + "ColorMultiplier": 1, + "FadeDuration": 0.1 + }, + "ImageRUIDs": { + "HighlightedSprite": null, + "PressedSprite": null, + "SelectedSprite": null, + "DisabledSprite": null + }, + "KeyCode": 0, + "OverrideSorting": false, + "Transition": 1, + "Enable": true } ], "@version": 1