refactor(cb): 컨트롤러 횡단 관심사 모듈 분리 (이동·본문 무변경)
화면 전환·NPC·포지션 관심사를 state.mjs/render.mjs/runend.mjs에서 전용 모듈로 분리. 런타임은 단일 SlayDeckController codeblock 유지. - state.mjs → screens.mjs 개명 (화면 라우팅·버튼 바인딩) - npc.mjs 신규: OnLobbyNpcInteract - navigation.mjs 신규: GoLobbyMap·TeleportToActMap (월드 텔레포트) - layout.mjs 신규: PositionMonsterSlot (UI 슬롯 배치) - gen-slaydeck.mjs import·spread 갱신 검증: tools/verify/cbset.mjs (순서 무관 집합 비교) = 189/189 무손실, 본문/exec/params 변경 0. cbgap GAP 0, 테스트 93/93. 산출물 재생성(SlayDeckController.codeblock) 포함 — 메서드 순서만 바뀜. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1342,44 +1342,6 @@
|
|||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
"Name": "ShowLobby"
|
"Name": "ShowLobby"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Return": {
|
|
||||||
"Type": "void",
|
|
||||||
"DefaultValue": null,
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": null
|
|
||||||
},
|
|
||||||
"Arguments": [],
|
|
||||||
"Code": "self.LobbyTpTries = 0\nlocal eventId = 0\nlocal function go()\n\tself.LobbyTpTries = self.LobbyTpTries + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil then\n\t\tif lp.CurrentMapName ~= \"lobby\" then\n\t\t\t_TeleportService:TeleportToMapPosition(lp, Vector3(-5, 0.03, 0), \"lobby\")\n\t\tend\n\t\t_TimerService:ClearTimer(eventId)\n\telseif self.LobbyTpTries > 50 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend\neventId = _TimerService:SetTimerRepeat(go, 0.1)",
|
|
||||||
"Scope": 2,
|
|
||||||
"ExecSpace": 6,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "GoLobbyMap"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Return": {
|
|
||||||
"Type": "void",
|
|
||||||
"DefaultValue": null,
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": null
|
|
||||||
},
|
|
||||||
"Arguments": [
|
|
||||||
{
|
|
||||||
"Type": "string",
|
|
||||||
"DefaultValue": "\"\"",
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "id"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Code": "if self.RunActive == true then\n\treturn\nend\nif id == \"run\" then\n\tself:ShowCharacterSelect()\nelseif id == \"codex\" then\n\tself:ShowCodex()\nelseif id == \"shop\" then\n\tself:ShowSoulShop()\nelseif id == \"board\" then\n\tself:ShowBoard()\nend",
|
|
||||||
"Scope": 2,
|
|
||||||
"ExecSpace": 6,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "OnLobbyNpcInteract"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"Type": "void",
|
"Type": "void",
|
||||||
@@ -1455,6 +1417,59 @@
|
|||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
"Name": "CloseBoard"
|
"Name": "CloseBoard"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Return": {
|
||||||
|
"Type": "void",
|
||||||
|
"DefaultValue": null,
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": null
|
||||||
|
},
|
||||||
|
"Arguments": [
|
||||||
|
{
|
||||||
|
"Type": "string",
|
||||||
|
"DefaultValue": "\"\"",
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Code": "if self.RunActive == true then\n\treturn\nend\nif id == \"run\" then\n\tself:ShowCharacterSelect()\nelseif id == \"codex\" then\n\tself:ShowCodex()\nelseif id == \"shop\" then\n\tself:ShowSoulShop()\nelseif id == \"board\" then\n\tself:ShowBoard()\nend",
|
||||||
|
"Scope": 2,
|
||||||
|
"ExecSpace": 6,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "OnLobbyNpcInteract"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Return": {
|
||||||
|
"Type": "void",
|
||||||
|
"DefaultValue": null,
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": null
|
||||||
|
},
|
||||||
|
"Arguments": [],
|
||||||
|
"Code": "self.LobbyTpTries = 0\nlocal eventId = 0\nlocal function go()\n\tself.LobbyTpTries = self.LobbyTpTries + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil then\n\t\tif lp.CurrentMapName ~= \"lobby\" then\n\t\t\t_TeleportService:TeleportToMapPosition(lp, Vector3(-5, 0.03, 0), \"lobby\")\n\t\tend\n\t\t_TimerService:ClearTimer(eventId)\n\telseif self.LobbyTpTries > 50 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend\neventId = _TimerService:SetTimerRepeat(go, 0.1)",
|
||||||
|
"Scope": 2,
|
||||||
|
"ExecSpace": 6,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "GoLobbyMap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Return": {
|
||||||
|
"Type": "void",
|
||||||
|
"DefaultValue": null,
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": null
|
||||||
|
},
|
||||||
|
"Arguments": [],
|
||||||
|
"Code": "local maps = { \"map01\", \"map02\", \"map03\", \"map04\", \"map05\" }\nlocal target = maps[self.Floor]\nif target == nil then\n\treturn\nend\nlocal lp = _UserService.LocalPlayer\nif lp == nil then\n\treturn\nend\nif lp.CurrentMapName == target then\n\treturn\nend\n_TeleportService:TeleportToMapPosition(lp, Vector3(-6, 0.03, 0), target)",
|
||||||
|
"Scope": 2,
|
||||||
|
"ExecSpace": 6,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "TeleportToActMap"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"Type": "void",
|
"Type": "void",
|
||||||
@@ -3937,21 +3952,6 @@
|
|||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
"Name": "SetJob"
|
"Name": "SetJob"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Return": {
|
|
||||||
"Type": "void",
|
|
||||||
"DefaultValue": null,
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": null
|
|
||||||
},
|
|
||||||
"Arguments": [],
|
|
||||||
"Code": "local maps = { \"map01\", \"map02\", \"map03\", \"map04\", \"map05\" }\nlocal target = maps[self.Floor]\nif target == nil then\n\treturn\nend\nlocal lp = _UserService.LocalPlayer\nif lp == nil then\n\treturn\nend\nif lp.CurrentMapName == target then\n\treturn\nend\n_TeleportService:TeleportToMapPosition(lp, Vector3(-6, 0.03, 0), target)",
|
|
||||||
"Scope": 2,
|
|
||||||
"ExecSpace": 6,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "TeleportToActMap"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"Type": "void",
|
"Type": "void",
|
||||||
@@ -4230,29 +4230,6 @@
|
|||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
"Name": "SetHpBar"
|
"Name": "SetHpBar"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Return": {
|
|
||||||
"Type": "void",
|
|
||||||
"DefaultValue": null,
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": null
|
|
||||||
},
|
|
||||||
"Arguments": [
|
|
||||||
{
|
|
||||||
"Type": "number",
|
|
||||||
"DefaultValue": null,
|
|
||||||
"SyncDirection": 0,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "slot"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Code": "local m = self.Monsters[slot]\nif m == nil or m.entity == nil or not isvalid(m.entity) then\n\treturn\nend\nlocal tr = m.entity.TransformComponent\nif tr == nil then\n\treturn\nend\nlocal wp = tr.WorldPosition\nlocal screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 1.4))\nlocal uipos = _UILogic:ScreenToUIPosition(screen)\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\te.UITransformComponent.anchoredPosition = uipos\nend",
|
|
||||||
"Scope": 2,
|
|
||||||
"ExecSpace": 6,
|
|
||||||
"Attributes": [],
|
|
||||||
"Name": "PositionMonsterSlot"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"Type": "void",
|
"Type": "void",
|
||||||
@@ -4291,6 +4268,29 @@
|
|||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
"Name": "RenderRun"
|
"Name": "RenderRun"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Return": {
|
||||||
|
"Type": "void",
|
||||||
|
"DefaultValue": null,
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": null
|
||||||
|
},
|
||||||
|
"Arguments": [
|
||||||
|
{
|
||||||
|
"Type": "number",
|
||||||
|
"DefaultValue": null,
|
||||||
|
"SyncDirection": 0,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "slot"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Code": "local m = self.Monsters[slot]\nif m == nil or m.entity == nil or not isvalid(m.entity) then\n\treturn\nend\nlocal tr = m.entity.TransformComponent\nif tr == nil then\n\treturn\nend\nlocal wp = tr.WorldPosition\nlocal screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 1.4))\nlocal uipos = _UILogic:ScreenToUIPosition(screen)\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\te.UITransformComponent.anchoredPosition = uipos\nend",
|
||||||
|
"Scope": 2,
|
||||||
|
"ExecSpace": 6,
|
||||||
|
"Attributes": [],
|
||||||
|
"Name": "PositionMonsterSlot"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Return": {
|
"Return": {
|
||||||
"Type": "any",
|
"Type": "any",
|
||||||
|
|||||||
21
tools/deck/cb/layout.mjs
Normal file
21
tools/deck/cb/layout.mjs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, ACT_COUNT, ACT_MAPS, LOBBY_MAP, LOBBY_SPAWN } from '../lib/codeblock.mjs';
|
||||||
|
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||||
|
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||||
|
|
||||||
|
export const layoutMethods = [
|
||||||
|
method('PositionMonsterSlot', `local m = self.Monsters[slot]
|
||||||
|
if m == nil or m.entity == nil or not isvalid(m.entity) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local tr = m.entity.TransformComponent
|
||||||
|
if tr == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local wp = tr.WorldPosition
|
||||||
|
local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y}))
|
||||||
|
local uipos = _UILogic:ScreenToUIPosition(screen)
|
||||||
|
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(slot))
|
||||||
|
if e ~= nil and e.UITransformComponent ~= nil then
|
||||||
|
e.UITransformComponent.anchoredPosition = uipos
|
||||||
|
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||||
|
];
|
||||||
34
tools/deck/cb/navigation.mjs
Normal file
34
tools/deck/cb/navigation.mjs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, ACT_COUNT, ACT_MAPS, LOBBY_MAP, LOBBY_SPAWN } from '../lib/codeblock.mjs';
|
||||||
|
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||||
|
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||||
|
|
||||||
|
export const navigationMethods = [
|
||||||
|
method('GoLobbyMap', `self.LobbyTpTries = 0
|
||||||
|
local eventId = 0
|
||||||
|
local function go()
|
||||||
|
self.LobbyTpTries = self.LobbyTpTries + 1
|
||||||
|
local lp = _UserService.LocalPlayer
|
||||||
|
if lp ~= nil then
|
||||||
|
if lp.CurrentMapName ~= "${LOBBY_MAP}" then
|
||||||
|
_TeleportService:TeleportToMapPosition(lp, ${LOBBY_SPAWN}, "${LOBBY_MAP}")
|
||||||
|
end
|
||||||
|
_TimerService:ClearTimer(eventId)
|
||||||
|
elseif self.LobbyTpTries > 50 then
|
||||||
|
_TimerService:ClearTimer(eventId)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
eventId = _TimerService:SetTimerRepeat(go, 0.1)`),
|
||||||
|
method('TeleportToActMap', `local maps = { ${ACT_MAPS.map((m) => `"${m}"`).join(', ')} }
|
||||||
|
local target = maps[self.Floor]
|
||||||
|
if target == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local lp = _UserService.LocalPlayer
|
||||||
|
if lp == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if lp.CurrentMapName == target then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
_TeleportService:TeleportToMapPosition(lp, Vector3(-6, 0.03, 0), target)`),
|
||||||
|
];
|
||||||
18
tools/deck/cb/npc.mjs
Normal file
18
tools/deck/cb/npc.mjs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, ACT_COUNT, ACT_MAPS, LOBBY_MAP, LOBBY_SPAWN } from '../lib/codeblock.mjs';
|
||||||
|
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||||
|
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||||
|
|
||||||
|
export const npcMethods = [
|
||||||
|
method('OnLobbyNpcInteract', `if self.RunActive == true then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if id == "run" then
|
||||||
|
self:ShowCharacterSelect()
|
||||||
|
elseif id == "codex" then
|
||||||
|
self:ShowCodex()
|
||||||
|
elseif id == "shop" then
|
||||||
|
self:ShowSoulShop()
|
||||||
|
elseif id == "board" then
|
||||||
|
self:ShowBoard()
|
||||||
|
end`, [{ Type: 'string', DefaultValue: '""', SyncDirection: 0, Attributes: [], Name: 'id' }]),
|
||||||
|
];
|
||||||
@@ -283,21 +283,6 @@ e.UITransformComponent.RectSize = Vector2(w, 14)`, [
|
|||||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' },
|
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' },
|
||||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'width' },
|
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'width' },
|
||||||
]),
|
]),
|
||||||
method('PositionMonsterSlot', `local m = self.Monsters[slot]
|
|
||||||
if m == nil or m.entity == nil or not isvalid(m.entity) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local tr = m.entity.TransformComponent
|
|
||||||
if tr == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local wp = tr.WorldPosition
|
|
||||||
local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y}))
|
|
||||||
local uipos = _UILogic:ScreenToUIPosition(screen)
|
|
||||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(slot))
|
|
||||||
if e ~= nil and e.UITransformComponent ~= nil then
|
|
||||||
e.UITransformComponent.anchoredPosition = uipos
|
|
||||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
|
||||||
method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then
|
method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then
|
||||||
self.TargetIndex = slot
|
self.TargetIndex = slot
|
||||||
self:RenderCombat()
|
self:RenderCombat()
|
||||||
|
|||||||
@@ -3,19 +3,6 @@ import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_
|
|||||||
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||||
|
|
||||||
export const runEndMethods = [
|
export const runEndMethods = [
|
||||||
method('TeleportToActMap', `local maps = { ${ACT_MAPS.map((m) => `"${m}"`).join(', ')} }
|
|
||||||
local target = maps[self.Floor]
|
|
||||||
if target == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local lp = _UserService.LocalPlayer
|
|
||||||
if lp == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if lp.CurrentMapName == target then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
_TeleportService:TeleportToMapPosition(lp, Vector3(-6, 0.03, 0), target)`),
|
|
||||||
method('ShowResult', `self:SetText("/ui/RunUIGroup/CombatHud/Result", text)
|
method('ShowResult', `self:SetText("/ui/RunUIGroup/CombatHud/Result", text)
|
||||||
local entity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/Result")
|
local entity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/Result")
|
||||||
if entity ~= nil then
|
if entity ~= nil then
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, A
|
|||||||
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||||
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||||
|
|
||||||
export const stateMethods = [
|
export const screensMethods = [
|
||||||
method('HideGameHud', `self:SetEntityEnabled("/ui/DefaultGroup/Button_Attack", false)
|
method('HideGameHud', `self:SetEntityEnabled("/ui/DefaultGroup/Button_Attack", false)
|
||||||
self:SetEntityEnabled("/ui/DefaultGroup/Button_Jump", false)
|
self:SetEntityEnabled("/ui/DefaultGroup/Button_Jump", false)
|
||||||
self:SetEntityEnabled("/ui/DefaultGroup/UIJoystick", false)
|
self:SetEntityEnabled("/ui/DefaultGroup/UIJoystick", false)
|
||||||
@@ -135,33 +135,6 @@ self:SetEntityEnabled("/ui/LobbyUIGroup/SoulShopHud", false)
|
|||||||
self:BindLobbyButtons()
|
self:BindLobbyButtons()
|
||||||
self:BindMenuButtons()
|
self:BindMenuButtons()
|
||||||
self:GoLobbyMap()`),
|
self:GoLobbyMap()`),
|
||||||
method('GoLobbyMap', `self.LobbyTpTries = 0
|
|
||||||
local eventId = 0
|
|
||||||
local function go()
|
|
||||||
self.LobbyTpTries = self.LobbyTpTries + 1
|
|
||||||
local lp = _UserService.LocalPlayer
|
|
||||||
if lp ~= nil then
|
|
||||||
if lp.CurrentMapName ~= "${LOBBY_MAP}" then
|
|
||||||
_TeleportService:TeleportToMapPosition(lp, ${LOBBY_SPAWN}, "${LOBBY_MAP}")
|
|
||||||
end
|
|
||||||
_TimerService:ClearTimer(eventId)
|
|
||||||
elseif self.LobbyTpTries > 50 then
|
|
||||||
_TimerService:ClearTimer(eventId)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
eventId = _TimerService:SetTimerRepeat(go, 0.1)`),
|
|
||||||
method('OnLobbyNpcInteract', `if self.RunActive == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if id == "run" then
|
|
||||||
self:ShowCharacterSelect()
|
|
||||||
elseif id == "codex" then
|
|
||||||
self:ShowCodex()
|
|
||||||
elseif id == "shop" then
|
|
||||||
self:ShowSoulShop()
|
|
||||||
elseif id == "board" then
|
|
||||||
self:ShowBoard()
|
|
||||||
end`, [{ Type: 'string', DefaultValue: '""', SyncDirection: 0, Attributes: [], Name: 'id' }]),
|
|
||||||
method('RenderSoulLabel', `local s = self.SoulPoints or 0
|
method('RenderSoulLabel', `local s = self.SoulPoints or 0
|
||||||
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "영혼 " .. string.format("%d", s))
|
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "영혼 " .. string.format("%d", s))
|
||||||
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "영혼 " .. string.format("%d", s))`),
|
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "영혼 " .. string.format("%d", s))`),
|
||||||
@@ -3,7 +3,10 @@
|
|||||||
import { POTIONS } from './lib/data.mjs';
|
import { POTIONS } from './lib/data.mjs';
|
||||||
import { prop, codeblock, RUN_LENGTH } from './lib/codeblock.mjs';
|
import { prop, codeblock, RUN_LENGTH } from './lib/codeblock.mjs';
|
||||||
import { bootMethods } from './cb/boot.mjs';
|
import { bootMethods } from './cb/boot.mjs';
|
||||||
import { stateMethods } from './cb/state.mjs';
|
import { screensMethods } from './cb/screens.mjs';
|
||||||
|
import { npcMethods } from './cb/npc.mjs';
|
||||||
|
import { navigationMethods } from './cb/navigation.mjs';
|
||||||
|
import { layoutMethods } from './cb/layout.mjs';
|
||||||
import { soulMethods } from './cb/soul.mjs';
|
import { soulMethods } from './cb/soul.mjs';
|
||||||
import { charSelectMethods } from './cb/charselect.mjs';
|
import { charSelectMethods } from './cb/charselect.mjs';
|
||||||
import { runMethods } from './cb/run.mjs';
|
import { runMethods } from './cb/run.mjs';
|
||||||
@@ -166,7 +169,9 @@ function writeCodeblocks() {
|
|||||||
prop('any', 'NextTurnAddCards'),
|
prop('any', 'NextTurnAddCards'),
|
||||||
], [
|
], [
|
||||||
...bootMethods,
|
...bootMethods,
|
||||||
...stateMethods,
|
...screensMethods,
|
||||||
|
...npcMethods,
|
||||||
|
...navigationMethods,
|
||||||
...soulMethods,
|
...soulMethods,
|
||||||
...charSelectMethods,
|
...charSelectMethods,
|
||||||
...runMethods,
|
...runMethods,
|
||||||
@@ -177,6 +182,7 @@ function writeCodeblocks() {
|
|||||||
...jobMethods,
|
...jobMethods,
|
||||||
...runEndMethods,
|
...runEndMethods,
|
||||||
...renderMethods,
|
...renderMethods,
|
||||||
|
...layoutMethods,
|
||||||
...rewardMethods,
|
...rewardMethods,
|
||||||
...itemMethods,
|
...itemMethods,
|
||||||
...tooltipMethods,
|
...tooltipMethods,
|
||||||
|
|||||||
40
tools/verify/cbset.mjs
Normal file
40
tools/verify/cbset.mjs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// 순서 무관 codeblock 메서드 집합 비교. 본문 미출력 — 이름·차이 카운트만.
|
||||||
|
// 메서드 이동 리팩터의 무손실 검증용: 워킹트리 codeblock vs ref(기본 HEAD).
|
||||||
|
// 사용: node tools/verify/cbset.mjs [ref]
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import { execSync } from 'node:child_process';
|
||||||
|
|
||||||
|
const PATH = 'RootDesk/MyDesk/SlayDeckController.codeblock';
|
||||||
|
const ref = process.argv[2] || 'HEAD';
|
||||||
|
|
||||||
|
function methodsOf(jsonText) {
|
||||||
|
const obj = JSON.parse(jsonText);
|
||||||
|
const arr = obj.ContentProto.Json.Methods;
|
||||||
|
const map = new Map();
|
||||||
|
for (const m of arr) {
|
||||||
|
map.set(m.Name, { code: m.Code, exec: m.ExecSpace, params: JSON.stringify(m.Parameters || []) });
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
const work = methodsOf(readFileSync(PATH, 'utf8'));
|
||||||
|
const base = methodsOf(execSync(`git show ${ref}:${PATH}`, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }));
|
||||||
|
|
||||||
|
const onlyWork = [...work.keys()].filter((k) => !base.has(k));
|
||||||
|
const onlyBase = [...base.keys()].filter((k) => !work.has(k));
|
||||||
|
const changed = [];
|
||||||
|
for (const k of work.keys()) {
|
||||||
|
if (!base.has(k)) continue;
|
||||||
|
const a = work.get(k);
|
||||||
|
const b = base.get(k);
|
||||||
|
if (a.code !== b.code || a.exec !== b.exec || a.params !== b.params) changed.push(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`ref=${ref} work=${work.size} base=${base.size}`);
|
||||||
|
console.log(`only-in-work (${onlyWork.length}): ${onlyWork.join(', ') || '-'}`);
|
||||||
|
console.log(`only-in-base (${onlyBase.length}): ${onlyBase.join(', ') || '-'}`);
|
||||||
|
console.log(`body/exec/params changed (${changed.length}): ${changed.join(', ') || '-'}`);
|
||||||
|
|
||||||
|
const ok = onlyWork.length === 0 && onlyBase.length === 0 && changed.length === 0;
|
||||||
|
console.log(ok ? 'RESULT: IDENTICAL SET (무손실)' : 'RESULT: DIFFERENCES ABOVE');
|
||||||
|
process.exit(ok ? 0 : 1);
|
||||||
Reference in New Issue
Block a user