local Tinkr = ... local Draw = Tinkr.Util.Draw:New() local Builder = Tinkr.Util.GUIBuilder:New { config = "node_finder_config" } local nodes = { -- Mining nodes [413047] = {name = "Aqirite", type = "mining"}, [434556] = {name = "Aqirite Chunk", type = "mining"}, [413881] = {name = "Aqirite Seam", type = "mining"}, [413046] = {name = "Bismuth", type = "mining"}, [452082] = {name = "Bismuth", type = "mining"}, [452080] = {name = "Bismuth", type = "mining"}, [440211] = {name = "Bismuth", type = "mining"}, [452076] = {name = "Bismuth", type = "mining"}, [452081] = {name = "Bismuth", type = "mining"}, [452079] = {name = "Bismuth", type = "mining"}, [434558] = {name = "Bismuth Chunk", type = "mining"}, [413880] = {name = "Bismuth Seam", type = "mining"}, [413897] = {name = "Camouflaged Aqirite", type = "mining"}, [413889] = {name = "Camouflaged Bismuth", type = "mining"}, [413907] = {name = "Camouflaged Ironclaw", type = "mining"}, [413890] = {name = "Crystallized Aqirite", type = "mining"}, [413883] = {name = "Crystallized Bismuth", type = "mining"}, [413900] = {name = "Crystallized Ironclaw", type = "mining"}, [413895] = {name = "EZ-Mine Aqirite", type = "mining"}, [413886] = {name = "EZ-Mine Bismuth", type = "mining"}, [413905] = {name = "EZ-Mine Ironclaw", type = "mining"}, [413049] = {name = "Ironclaw", type = "mining"}, [452075] = {name = "Ironclaw", type = "mining"}, [452067] = {name = "Ironclaw", type = "mining"}, [440219] = {name = "Ironclaw", type = "mining"}, [452063] = {name = "Ironclaw", type = "mining"}, [452070] = {name = "Ironclaw", type = "mining"}, [452083] = {name = "Ironclaw", type = "mining"}, [452066] = {name = "Ironclaw", type = "mining"}, [440214] = {name = "Ironclaw", type = "mining"}, [452060] = {name = "Ironclaw", type = "mining"}, [434557] = {name = "Ironclaw Chunk", type = "mining"}, [413882] = {name = "Ironclaw Seam", type = "mining"}, [446351] = {name = "Loose Crystal Shard", type = "mining"}, [446347] = {name = "Loose Crystal Shard", type = "mining"}, [446352] = {name = "Loose Crystal Shard", type = "mining"}, [446349] = {name = "Loose Crystal Shard", type = "mining"}, [446343] = {name = "Loose Crystal Shard", type = "mining"}, [413875] = {name = "Rich Aqirite", type = "mining"}, [413874] = {name = "Rich Bismuth", type = "mining"}, [413877] = {name = "Rich Ironclaw", type = "mining"}, [414113] = {name = "Sivstone Deposit", type = "mining"}, [430351] = {name = "Webbed Ore Deposit", type = "mining"}, [430352] = {name = "Webbed Ore Deposit", type = "mining"}, [430335] = {name = "Webbed Ore Deposit", type = "mining"}, [413892] = {name = "Weeping Aqirite", type = "mining"}, [413884] = {name = "Weeping Bismuth", type = "mining"}, [413902] = {name = "Weeping Ironclaw", type = "mining"}, -- Herb nodes [414331] = {name = "Altered Luredrop", type = "herb"}, [414330] = {name = "Altered Mycobloom", type = "herb"}, [414332] = {name = "Altered Orbinid", type = "herb"}, [414319] = {name = "Arathor's Spear", type = "herb"}, [454081] = {name = "Blessing Blossom", type = "herb"}, [454086] = {name = "Blessing Blossom", type = "herb"}, [414318] = {name = "Blessing Blossom", type = "herb"}, [414344] = {name = "Camouflaged Arathor's Spear", type = "herb"}, [414343] = {name = "Camouflaged Blessing Blossom", type = "herb"}, [454078] = {name = "Camouflaged Blessing Blossom", type = "herb"}, [454083] = {name = "Camouflaged Blessing Blossom", type = "herb"}, [414341] = {name = "Camouflaged Luredrop", type = "herb"}, [454007] = {name = "Camouflaged Luredrop", type = "herb"}, [454051] = {name = "Camouflaged Luredrop", type = "herb"}, [454065] = {name = "Camouflaged Mycobloom", type = "herb"}, [414340] = {name = "Camouflaged Mycobloom", type = "herb"}, [454068] = {name = "Camouflaged Mycobloom", type = "herb"}, [454073] = {name = "Camouflaged Mycobloom", type = "herb"}, [414342] = {name = "Camouflaged Orbinid", type = "herb"}, [414329] = {name = "Crystallized Arathor's Spear", type = "herb"}, [414328] = {name = "Crystallized Blessing Blossom", type = "herb"}, [414326] = {name = "Crystallized Luredrop", type = "herb"}, [414325] = {name = "Crystallized Mycobloom", type = "herb"}, [414327] = {name = "Crystallized Orbinid", type = "herb"}, [414339] = {name = "Irradiated Arathor's Spear", type = "herb"}, [454079] = {name = "Irradiated Blessing Blossom", type = "herb"}, [454084] = {name = "Irradiated Blessing Blossom", type = "herb"}, [414338] = {name = "Irradiated Blessing Blossom", type = "herb"}, [454008] = {name = "Irradiated Luredrop", type = "herb"}, [454053] = {name = "Irradiated Luredrop", type = "herb"}, [414336] = {name = "Irradiated Luredrop", type = "herb"}, [414335] = {name = "Irradiated Mycobloom", type = "herb"}, [454066] = {name = "Irradiated Mycobloom", type = "herb"}, [454069] = {name = "Irradiated Mycobloom", type = "herb"}, [454074] = {name = "Irradiated Mycobloom", type = "herb"}, [414337] = {name = "Irradiated Orbinid", type = "herb"}, [444029] = {name = "Light-Bathed Lotus", type = "herb"}, [444030] = {name = "Light-Bathed Lotus", type = "herb"}, [444028] = {name = "Light-Bathed Lotus", type = "herb"}, [452977] = {name = "Luredrop", type = "herb"}, [454010] = {name = "Luredrop", type = "herb"}, [440189] = {name = "Luredrop", type = "herb"}, [452975] = {name = "Luredrop", type = "herb"}, [440164] = {name = "Luredrop", type = "herb"}, [452972] = {name = "Luredrop", type = "herb"}, [454055] = {name = "Luredrop", type = "herb"}, [440162] = {name = "Luredrop", type = "herb"}, [452978] = {name = "Luredrop", type = "herb"}, [452976] = {name = "Luredrop", type = "herb"}, [414316] = {name = "Luredrop", type = "herb"}, [454545] = {name = "Luredrop", type = "herb"}, [440167] = {name = "Luredrop", type = "herb"}, [452973] = {name = "Luredrop", type = "herb"}, [440163] = {name = "Luredrop", type = "herb"}, [452971] = {name = "Luredrop", type = "herb"}, [452979] = {name = "Luredrop", type = "herb"}, [414324] = {name = "Lush Arathor's Spear", type = "herb"}, [454080] = {name = "Lush Blessing Blossom", type = "herb"}, [414323] = {name = "Lush Blessing Blossom", type = "herb"}, [454085] = {name = "Lush Blessing Blossom", type = "herb"}, [454009] = {name = "Lush Luredrop", type = "herb"}, [414321] = {name = "Lush Luredrop", type = "herb"}, [454054] = {name = "Lush Luredrop", type = "herb"}, [454070] = {name = "Lush Mycobloom", type = "herb"}, [414320] = {name = "Lush Mycobloom", type = "herb"}, [454075] = {name = "Lush Mycobloom", type = "herb"}, [454062] = {name = "Lush Mycobloom", type = "herb"}, [414322] = {name = "Lush Orbinid", type = "herb"}, [440200] = {name = "Mycobloom", type = "herb"}, [454063] = {name = "Mycobloom", type = "herb"}, [414315] = {name = "Mycobloom", type = "herb"}, [440201] = {name = "Mycobloom", type = "herb"}, [440193] = {name = "Mycobloom", type = "herb"}, [454071] = {name = "Mycobloom", type = "herb"}, [454076] = {name = "Mycobloom", type = "herb"}, [440204] = {name = "Mycobloom", type = "herb"}, [452957] = {name = "Orbinid", type = "herb"}, [414317] = {name = "Orbinid", type = "herb"}, [452964] = {name = "Orbinid", type = "herb"}, [452955] = {name = "Orbinid", type = "herb"}, [452962] = {name = "Orbinid", type = "herb"}, [452953] = {name = "Orbinid", type = "herb"}, [452960] = {name = "Orbinid", type = "herb"}, [452950] = {name = "Orbinid", type = "herb"}, [452969] = {name = "Orbinid", type = "herb"}, [452958] = {name = "Orbinid", type = "herb"}, [452965] = {name = "Orbinid", type = "herb"}, [452956] = {name = "Orbinid", type = "herb"}, [452963] = {name = "Orbinid", type = "herb"}, [452954] = {name = "Orbinid", type = "herb"}, [452961] = {name = "Orbinid", type = "herb"}, [452952] = {name = "Orbinid", type = "herb"}, [452959] = {name = "Orbinid", type = "herb"}, [452948] = {name = "Orbinid", type = "herb"}, [452968] = {name = "Orbinid", type = "herb"}, [421629] = {name = "Smellsage Shrub", type = "herb"}, [423363] = {name = "Sporefused Arathor's Spear", type = "herb"}, [423364] = {name = "Sporefused Blessing Blossom", type = "herb"}, [454077] = {name = "Sporefused Blessing Blossom", type = "herb"}, [454082] = {name = "Sporefused Blessing Blossom", type = "herb"}, [454006] = {name = "Sporefused Luredrop", type = "herb"}, [454050] = {name = "Sporefused Luredrop", type = "herb"}, [423366] = {name = "Sporefused Luredrop", type = "herb"}, [454072] = {name = "Sporefused Mycobloom", type = "herb"}, [423367] = {name = "Sporefused Mycobloom", type = "herb"}, [454064] = {name = "Sporefused Mycobloom", type = "herb"}, [454067] = {name = "Sporefused Mycobloom", type = "herb"}, [423368] = {name = "Sporefused Orbinid", type = "herb"}, [429639] = {name = "Sporelusive Arathor's Spear", type = "herb"}, [429644] = {name = "Sporelusive Arathor's Spear", type = "herb"}, [429640] = {name = "Sporelusive Blessing Blossom", type = "herb"}, [429645] = {name = "Sporelusive Blessing Blossom", type = "herb"}, [429646] = {name = "Sporelusive Luredrop", type = "herb"}, [429641] = {name = "Sporelusive Luredrop", type = "herb"}, [429642] = {name = "Sporelusive Mycobloom", type = "herb"}, [429647] = {name = "Sporelusive Mycobloom", type = "herb"}, [429643] = {name = "Sporelusive Orbinid", type = "herb"}, [429648] = {name = "Sporelusive Orbinid", type = "herb"}, [444010] = {name = "Tough Ivy", type = "herb"}, [444005] = {name = "Tough Ivy", type = "herb"}, [444006] = {name = "Tough Ivy", type = "herb"} } local function GetNodeInfo(objectId) return nodes[objectId] end -- Define the crystal shape once, outside of the function local baseSize = 1.5 local height = 3 local halfHeight = height / 2 local crystal_shape = { -- Lines from v1 to v2, v3, v4, v5 {0, 0, 0, -baseSize, -baseSize, halfHeight}, {0, 0, 0, baseSize, -baseSize, halfHeight}, {0, 0, 0, baseSize, baseSize, halfHeight}, {0, 0, 0, -baseSize, baseSize, halfHeight}, -- Lines between v2-v3, v3-v4, v4-v5, v5-v2 {-baseSize, -baseSize, halfHeight, baseSize, -baseSize, halfHeight}, { baseSize, -baseSize, halfHeight, baseSize, baseSize, halfHeight}, { baseSize, baseSize, halfHeight, -baseSize, baseSize, halfHeight}, {-baseSize, baseSize, halfHeight, -baseSize, -baseSize, halfHeight}, -- Lines from v2, v3, v4, v5 to v6 {-baseSize, -baseSize, halfHeight, 0, 0, height}, { baseSize, -baseSize, halfHeight, 0, 0, height}, { baseSize, baseSize, halfHeight, 0, 0, height}, {-baseSize, baseSize, halfHeight, 0, 0, height}, } -- Modify the DrawCrystalNode function local function DrawCrystalNode(draw, nx, ny, nz, color) draw:SetColor(color) draw:SetWidth(2) draw:SetAlpha(200) local bobHeight = math.sin(GetTime() * 4) * 0.5 local baseZ = nz + 5 + bobHeight -- Use the pre-defined crystal_shape and position offsets draw:Array(crystal_shape, nx, ny, baseZ) -- Draw a small sphere at the top for emphasis draw:Circle(nx, ny, baseZ + height + 0.5, 0.3) end local function DrawNode(draw, nodeInfo, nx, ny, nz, objectId) local px, py, pz = ObjectRawPosition('player') local dist = FastDistance(px, py, pz, nx, ny, nz) local nodeType = nodeInfo.type local shouldDraw = false local color if nodeType == "mining" and Builder:GetConfig("show_mining") == "yes" and Builder:GetConfig("show_mining_" .. objectId) == "yes" then color = {0, 0, 255} shouldDraw = true elseif nodeType == "herb" and Builder:GetConfig("show_herbs") == "yes" and Builder:GetConfig("show_herb_" .. objectId) == "yes" then color = {0, 255, 0} shouldDraw = true end if shouldDraw then DrawCrystalNode(draw, nx, ny, nz, color) if Builder:GetConfig("draw_lines") == "yes" then draw:SetColor(color) draw:Line(px, py, pz, nx, ny, nz) end draw:SetColor(255, 255, 255) local displayText = string.format("%s [%dy]", nodeInfo.name, math.floor(dist)) draw:Text(displayText, "SourceCodePro", nx, ny, nz + 9) end end Draw:Sync(function(draw) for _, object in ipairs(Objects()) do if ObjectType(object) == 8 then local objectId = ObjectId(object) local nodeInfo = GetNodeInfo(objectId) if nodeInfo and ObjectLootable(object) then local nx, ny, nz = ObjectRawPosition(object) DrawNode(draw, nodeInfo, nx, ny, nz, objectId) end end end end) -- Modify the SavePreferences function local function SavePreferences() for id, node in pairs(nodes) do local key = "show_" .. node.type .. "_" .. id local value = Builder:GetConfig(key) Builder:SetConfig(key, value) end print("Node preferences saved!") end local MainSettingsTab = Builder:Tab { title = "Main Settings", content = { Builder:Checkbox { key = "show_mining", label = "Show Mining Nodes", -- description = "Toggle visibility of mining nodes.", default = "yes" }, Builder:Checkbox { key = "show_herbs", label = "Show Herb Nodes", -- description = "Toggle visibility of herb nodes.", default = "yes" }, Builder:Checkbox { key = "draw_lines", label = "Draw Lines to Nodes", description = "Draw lines between the player and visible nodes.", default = "yes" }, } } local DetailedFilterTab = Builder:Tab { title = "Detailed Filters", content = { Builder:Group { key = "mining_nodes_group", title = "Mining Nodes", content = (function() local elements = {} for id, node in pairs(nodes) do if node.type == "mining" then table.insert(elements, Builder:Checkbox { key = "show_mining_" .. id, label = node.name, -- description = "Toggle visibility of " .. node.name, default = "yes" }) end end return elements end)() }, Builder:Group { key = "herb_nodes_group", title = "Herb Nodes", content = (function() local elements = {} for id, node in pairs(nodes) do if node.type == "herb" then table.insert(elements, Builder:Checkbox { key = "show_herb_" .. id, label = node.name, -- description = "Toggle visibility of " .. node.name, default = "yes" }) end end return elements end)() }, Builder:Button { key = "save_preferences_button", text = "Save Preferences", onClick = function() SavePreferences() end } } } local MainWindow = Builder:Window { key = "node_finder_window", title = "Node Finder Settings", width = 400, -- Increased width to accommodate more content height = 600, -- Increased height to accommodate more content content = { Builder:TabGroup { key = "main_tabs", tabs = { MainSettingsTab, DetailedFilterTab, } } } } Builder:Build(MainWindow) Draw:Enable()