feat: 노드 맵 UI 강화 — 아이콘 노드 + 다크 배경 (nodeicons.json 외부화) #58

Merged
maple merged 7 commits from feature/node-map-ui into main 2026-06-15 23:05:27 +09:00
3 changed files with 2358 additions and 2 deletions
Showing only changes of commit 67d21a9619 - Show all commits

View File

@@ -3749,7 +3749,7 @@
"Name": "id"
}
],
"Code": "local base = \"/ui/DefaultGroup/MapHud/Node_\" .. id\nlocal e = _EntityService:GetEntityByPath(base)\nif e == nil then\n\treturn\nend\nlocal node = self.MapNodes[id]\nif node == nil then\n\te.Enable = false\n\treturn\nend\ne.Enable = true\nlocal ruid = self.NodeIcons[node.type]\nif ruid == nil then\n\truid = self.NodeIcons[\"combat\"]\nend\nif e.SpriteGUIRendererComponent ~= nil and ruid ~= nil then\n\te.SpriteGUIRendererComponent.ImageRUID = ruid\nend\nlocal reachable = self:IsReachable(id)\nlocal visited = false\nif self.VisitedNodes ~= nil then\n\tfor i = 1, #self.VisitedNodes do\n\t\tif self.VisitedNodes[i] == id then visited = true end\n\tend\nend\nif e.SpriteGUIRendererComponent ~= nil then\n\tif id == self.CurrentNodeId then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 0.82, 0.3, 1)\n\telseif visited == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(0.5, 0.5, 0.55, 0.9)\n\telseif reachable == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\telse\n\t\te.SpriteGUIRendererComponent.Color = Color(0.4, 0.4, 0.45, 0.45)\n\tend\nend\nif e.ButtonComponent ~= nil then\n\te.ButtonComponent.Enable = reachable\nend",
"Code": "local base = \"/ui/DefaultGroup/MapHud/Node_\" .. id\nlocal e = _EntityService:GetEntityByPath(base)\nif e == nil then\n\treturn\nend\nlocal node = self.MapNodes[id]\nif node == nil then\n\te.Enable = false\n\treturn\nend\ne.Enable = true\nlocal ruid = self.NodeIcons[node.type]\nif ruid == nil then\n\truid = self.NodeIcons[\"combat\"]\nend\nif e.SpriteGUIRendererComponent ~= nil and ruid ~= nil then\n\te.SpriteGUIRendererComponent.ImageRUID = ruid\nend\nlocal reachable = self:IsReachable(id)\nlocal visited = false\nif self.VisitedNodes ~= nil then\n\tfor i = 1, #self.VisitedNodes do\n\t\tif self.VisitedNodes[i] == id then visited = true end\n\tend\nend\nif e.SpriteGUIRendererComponent ~= nil then\n\tif id == self.CurrentNodeId then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 0.82, 0.3, 1)\n\telseif visited == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(0.5, 0.5, 0.55, 0.9)\n\telseif reachable == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\telse\n\t\te.SpriteGUIRendererComponent.Color = Color(0.68, 0.68, 0.72, 0.85)\n\tend\nend\nif e.ButtonComponent ~= nil then\n\te.ButtonComponent.Enable = reachable\nend",
"Scope": 2,
"ExecSpace": 6,
"Attributes": [],

View File

@@ -1773,6 +1773,59 @@ function upsertUi() {
for (let c = 1; c <= MAP_COLS; c++) {
pushDots(`r${MAP_ROWS}c${c}_b`, { x: nodeX(MAP_ROWS), y: nodeY(c) }, BOSS_POS);
}
// 노드 종류 범례 (우측 하단) — 각 타입 아이콘 + 이름
const LEGEND = [['combat', '전투'], ['elite', '엘리트'], ['boss', '보스'], ['shop', '상점'], ['rest', '휴식'], ['treasure', '보물']];
const lgW = 300, lgH = 312;
map.push(entity({
id: guid('map', 991),
path: '/ui/DefaultGroup/MapHud/Legend',
modelId: 'uisprite', entryId: 'UISprite',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent',
displayOrder: 4,
components: [
transform({ parentW: 1920, parentH: 1080, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: lgW, y: lgH }, pos: { x: 760, y: -334 } }),
sprite({ color: { r: 0.08, g: 0.09, b: 0.14, a: 0.86 }, type: 1, raycast: false }),
],
}));
map.push(entity({
id: guid('map', 992),
path: '/ui/DefaultGroup/MapHud/Legend/LegendTitle',
modelId: 'uitext', entryId: 'UIText',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.TextComponent',
displayOrder: 1,
components: [
transform({ parentW: lgW, parentH: lgH, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: lgW - 20, y: 32 }, pos: { x: 0, y: lgH / 2 - 26 } }),
sprite({ color: TRANSPARENT }),
text({ value: '노드 종류', fontSize: 22, bold: true, color: GOLD, alignment: 4 }),
],
}));
let lgId = 993;
LEGEND.forEach(([t, ko], i) => {
const rowY = lgH / 2 - 78 - i * 38;
map.push(entity({
id: guid('map', lgId++),
path: `/ui/DefaultGroup/MapHud/Legend/Icon_${t}`,
modelId: 'uisprite', entryId: 'UISprite',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent',
displayOrder: 2,
components: [
transform({ parentW: lgW, parentH: lgH, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: 36, y: 36 }, pos: { x: -lgW / 2 + 38, y: rowY } }),
sprite({ dataId: NODEICONS.icons[t], color: { r: 1, g: 1, b: 1, a: 1 }, type: 0, raycast: false }),
],
}));
map.push(entity({
id: guid('map', lgId++),
path: `/ui/DefaultGroup/MapHud/Legend/Label_${t}`,
modelId: 'uitext', entryId: 'UIText',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.TextComponent',
displayOrder: 2,
components: [
transform({ parentW: lgW, parentH: lgH, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: lgW - 110, y: 30 }, pos: { x: 32, y: rowY } }),
sprite({ color: TRANSPARENT }),
text({ value: ko, fontSize: 19, bold: false, color: { r: 0.9, g: 0.92, b: 0.96, a: 1 }, alignment: 4 }),
],
}));
});
emit('MapHud', map);
const shop = [];
@@ -5661,7 +5714,7 @@ if e.SpriteGUIRendererComponent ~= nil then
elseif reachable == true then
e.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)
else
e.SpriteGUIRendererComponent.Color = Color(0.4, 0.4, 0.45, 0.45)
e.SpriteGUIRendererComponent.Color = Color(0.68, 0.68, 0.72, 0.85)
end
end
if e.ButtonComponent ~= nil then

File diff suppressed because it is too large Load Diff