메이커가 UI를 6개 UIGroup으로 분리하면서 발생한 2개 버그(시작이 MainMenu가 아니라 로비·NPC 상호작용 무반응) 근본 수정. 메이커 MCP 플레이테스트로 확정: - 원인1: 새 UIGroup(Select/Lobby/Run/Deck)이 DefaultShow=false라 시작 시 비활성. → ActivateUIGroups(ClientOnly)로 그룹 :SetEnable(true) 활성화. - 원인2: 컨트롤러의 중첩 self:SetEntityEnabled(.Enable 토글)가 비-DefaultGroup 스코프를 잃음(ExecSpace 6 RPC 재디스패치). → SetEntityEnabled를 ClientOnly(2)로 바꿔 인라인 실행 → 모든 UIGroup 해석. (.Text/RectSize/ImageRUID 등 다른 속성은 중첩에서도 정상이라 SetText/SetHpBar는 무변경.) - 원인3: OnBeginPlay가 UI 로드 전 실행 → DeckUIGroup 로드까지 폴링 후 ActivateUIGroups + ShowMainMenu. 검증(플레이테스트): 부트→MainMenu·시작→로비+LobbyUIGroup·run NPC→charselect 전부 정상. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
202 lines
10 KiB
JavaScript
202 lines
10 KiB
JavaScript
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 stateMethods = [
|
|
method('HideGameHud', `self:SetEntityEnabled("/ui/DefaultGroup/Button_Attack", false)
|
|
self:SetEntityEnabled("/ui/DefaultGroup/Button_Jump", false)
|
|
self:SetEntityEnabled("/ui/DefaultGroup/UIJoystick", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/DeckHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/CardHand", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/RewardHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/MapHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/ShopHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/RestHud", false)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/TreasureHud", false)
|
|
self:SetEntityEnabled("/ui/SelectUIGroup/JobChoiceHud", false)
|
|
self:SetEntityEnabled("/ui/SelectUIGroup/JobSelectHud", false)
|
|
self:SetEntityEnabled("/ui/DeckUIGroup/DeckInspectHud", false)
|
|
self:SetEntityEnabled("/ui/DeckUIGroup/DeckAllHud", false)
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/LobbyHud", false)
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/BoardHud", false)
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/SoulShopHud", false)`),
|
|
method('ActivateUIGroups', `local function grp(n)
|
|
local g = _EntityService:GetEntityByPath("/ui/" .. n)
|
|
if g ~= nil then g:SetEnable(true) end
|
|
end
|
|
grp("SelectUIGroup")
|
|
grp("LobbyUIGroup")
|
|
grp("RunUIGroup")
|
|
grp("DeckUIGroup")`, [], 2),
|
|
method('ShowState', `self:HideGameHud()
|
|
self:SetEntityEnabled("/ui/DefaultGroup/MainMenu", state == "menu")
|
|
self:SetEntityEnabled("/ui/SelectUIGroup/CharacterSelectHud", state == "charselect")
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/LobbyHud", state == "lobby")
|
|
if state == "map" then
|
|
self:SetEntityEnabled("/ui/RunUIGroup/MapHud", true)
|
|
elseif state == "combat" then
|
|
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud", true)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/DeckHud", true)
|
|
self:SetEntityEnabled("/ui/RunUIGroup/CardHand", true)
|
|
elseif state == "shop" then
|
|
self:SetEntityEnabled("/ui/RunUIGroup/ShopHud", true)
|
|
elseif state == "rest" then
|
|
self:SetEntityEnabled("/ui/RunUIGroup/RestHud", true)
|
|
elseif state == "treasure" then
|
|
self:SetEntityEnabled("/ui/RunUIGroup/TreasureHud", true)
|
|
end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'state' }]),
|
|
method('ShowMainMenu', `self.SelectedClass = ""
|
|
self:RenderAscension()
|
|
self:ShowState("menu")
|
|
self:SetText("/ui/DefaultGroup/MainMenu/Title", "메이플 덱 어드벤처")
|
|
self:SetText("/ui/DefaultGroup/MainMenu/Subtitle", "캐릭터를 고르고 덱을 만들어 모험을 시작하세요")
|
|
self:SetText("/ui/DefaultGroup/MainMenu/NewGameButton", "새 게임")
|
|
self:BindMenuButtons()`),
|
|
method('BindMenuButtons', `local buttonEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/NewGameButton")
|
|
if buttonEntity ~= nil and buttonEntity.ButtonComponent ~= nil then
|
|
if self.NewGameHandler ~= nil then
|
|
buttonEntity:DisconnectEvent(ButtonClickEvent, self.NewGameHandler)
|
|
self.NewGameHandler = nil
|
|
end
|
|
self.NewGameHandler = buttonEntity:ConnectEvent(ButtonClickEvent, function() self:ShowLobby() end)
|
|
end
|
|
local warrior = _EntityService:GetEntityByPath("/ui/SelectUIGroup/CharacterSelectHud/WarriorButton")
|
|
if warrior ~= nil and warrior.ButtonComponent ~= nil then
|
|
if self.WarriorSelectHandler ~= nil then
|
|
warrior:DisconnectEvent(ButtonClickEvent, self.WarriorSelectHandler)
|
|
self.WarriorSelectHandler = nil
|
|
end
|
|
self.WarriorSelectHandler = warrior:ConnectEvent(ButtonClickEvent, function() self:SelectClass("warrior") end)
|
|
end
|
|
local thief = _EntityService:GetEntityByPath("/ui/SelectUIGroup/CharacterSelectHud/ThiefButton")
|
|
if thief ~= nil and thief.ButtonComponent ~= nil then
|
|
if self.ThiefSelectHandler ~= nil then
|
|
thief:DisconnectEvent(ButtonClickEvent, self.ThiefSelectHandler)
|
|
self.ThiefSelectHandler = nil
|
|
end
|
|
self.ThiefSelectHandler = thief:ConnectEvent(ButtonClickEvent, function() self:SelectClass("bandit") end)
|
|
end
|
|
local mage = _EntityService:GetEntityByPath("/ui/SelectUIGroup/CharacterSelectHud/MageButton")
|
|
if mage ~= nil and mage.ButtonComponent ~= nil then
|
|
if self.MageSelectHandler ~= nil then
|
|
mage:DisconnectEvent(ButtonClickEvent, self.MageSelectHandler)
|
|
self.MageSelectHandler = nil
|
|
end
|
|
self.MageSelectHandler = mage:ConnectEvent(ButtonClickEvent, function() self:SelectClass("magician") end)
|
|
end
|
|
local allDeckClose = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Close")
|
|
if allDeckClose ~= nil and allDeckClose.ButtonComponent ~= nil then
|
|
if self.AllDeckCloseHandler ~= nil then
|
|
allDeckClose:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)
|
|
self.AllDeckCloseHandler = nil
|
|
end
|
|
self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
|
|
end
|
|
self:BindClassDeckTabs()
|
|
local start = _EntityService:GetEntityByPath("/ui/SelectUIGroup/CharacterSelectHud/StartButton")
|
|
if start ~= nil and start.ButtonComponent ~= nil then
|
|
if self.StartGameHandler ~= nil then
|
|
start:DisconnectEvent(ButtonClickEvent, self.StartGameHandler)
|
|
self.StartGameHandler = nil
|
|
end
|
|
self.StartGameHandler = start:ConnectEvent(ButtonClickEvent, function() self:StartNewGame() end)
|
|
end
|
|
local charBack = _EntityService:GetEntityByPath("/ui/SelectUIGroup/CharacterSelectHud/BackButton")
|
|
if charBack ~= nil and charBack.ButtonComponent ~= nil then
|
|
if self.CharBackHandler ~= nil then
|
|
charBack:DisconnectEvent(ButtonClickEvent, self.CharBackHandler)
|
|
self.CharBackHandler = nil
|
|
end
|
|
self.CharBackHandler = charBack:ConnectEvent(ButtonClickEvent, function() self:ShowLobby() end)
|
|
end
|
|
local ascMinus = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/AscMinus")
|
|
if ascMinus ~= nil and ascMinus.ButtonComponent ~= nil then
|
|
if self.AscMinusHandler ~= nil then
|
|
ascMinus:DisconnectEvent(ButtonClickEvent, self.AscMinusHandler)
|
|
self.AscMinusHandler = nil
|
|
end
|
|
self.AscMinusHandler = ascMinus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(-1) end)
|
|
end
|
|
local ascPlus = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/AscPlus")
|
|
if ascPlus ~= nil and ascPlus.ButtonComponent ~= nil then
|
|
if self.AscPlusHandler ~= nil then
|
|
ascPlus:DisconnectEvent(ButtonClickEvent, self.AscPlusHandler)
|
|
self.AscPlusHandler = nil
|
|
end
|
|
self.AscPlusHandler = ascPlus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(1) end)
|
|
end`),
|
|
method('ShowLobby', `self.SelectedClass = ""
|
|
self:RenderAscension()
|
|
self:RenderSoulLabel()
|
|
self:ShowState("lobby")
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/BoardHud", false)
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/SoulShopHud", false)
|
|
self:BindLobbyButtons()
|
|
self:BindMenuButtons()
|
|
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
|
|
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "영혼 " .. string.format("%d", s))
|
|
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "영혼 " .. string.format("%d", s))`),
|
|
method('BindLobbyButtons', `if self.LobbyBound == true then
|
|
return
|
|
end
|
|
self.LobbyBound = true
|
|
local function bindClick(path, fn)
|
|
local e = _EntityService:GetEntityByPath(path)
|
|
if e ~= nil and e.ButtonComponent ~= nil then
|
|
e:ConnectEvent(ButtonClickEvent, fn)
|
|
end
|
|
end
|
|
bindClick("/ui/LobbyUIGroup/LobbyHud/AscMinus", function() self:AdjustAscension(-1) end)
|
|
bindClick("/ui/LobbyUIGroup/LobbyHud/AscPlus", function() self:AdjustAscension(1) end)
|
|
bindClick("/ui/LobbyUIGroup/BoardHud/Close", function() self:CloseBoard() end)
|
|
bindClick("/ui/LobbyUIGroup/SoulShopHud/Close", function() self:CloseSoulShop() end)`),
|
|
method('ShowCodex', `self.CodexMode = true
|
|
self.ClassDeckMode = true
|
|
local close = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Close")
|
|
if close ~= nil and close.ButtonComponent ~= nil then
|
|
if self.AllDeckCloseHandler ~= nil then
|
|
close:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)
|
|
end
|
|
self.AllDeckCloseHandler = close:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
|
|
end
|
|
self:BindClassDeckTabs()
|
|
self:SetEntityEnabled("/ui/LobbyUIGroup/LobbyHud", false)
|
|
self:SetClassDeckTab("warrior")
|
|
local hud = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud")
|
|
if hud ~= nil then
|
|
hud.Enable = true
|
|
end
|
|
self:RenderAllDeck()`),
|
|
method('ShowBoard', `self:SetEntityEnabled("/ui/LobbyUIGroup/BoardHud", true)`),
|
|
method('CloseBoard', `self:SetEntityEnabled("/ui/LobbyUIGroup/BoardHud", false)`),
|
|
];
|