SHOW:
|
|
- or go back to the newest paste.
| 1 | --[[ | |
| 2 | Author: iikk_a (https://github.com/iikk-a/) | |
| 3 | Latest Edit: 20.01.2021 | |
| 4 | ||
| 5 | This code is absolutely not perfect, but it should be usable. | |
| 6 | No bugs have been found as of late. If you find a bug with this code, | |
| 7 | please leave an issue ticket on GitHub, so I can get to fixing it. | |
| 8 | ||
| 9 | Start up the application and select ores you want to track by clicking | |
| 10 | on them with your mouse cursor. You can deselect ores by clicking them again. | |
| 11 | ||
| 12 | If you have old tracers stuck mid air, just start this application again | |
| 13 | without picking ores and quit to clear the old tracers. | |
| 14 | ||
| 15 | Thank you. | |
| 16 | ]]-- | |
| 17 | ||
| 18 | ||
| 19 | -- Instantly quits if you don't have a neural interface | |
| 20 | local modules = peripheral.find("neuralInterface")
| |
| 21 | if not modules then error("must have a neural interface", 0) end
| |
| 22 | ||
| 23 | -- List so we can display all missing modules at once | |
| 24 | local missingModules = {}
| |
| 25 | ||
| 26 | -- Checks the existence of necessary modules | |
| 27 | if not modules.hasModule("plethora:scanner") then table.insert(missingModules, "Block Scanner") end
| |
| 28 | if not modules.hasModule("plethora:glasses") then table.insert(missingModules, "Overlay Glasses") end
| |
| 29 | ||
| 30 | -- If one or more modules are missing, error out | |
| 31 | if (#missingModules > 0) then error("Missing modules:\n - " .. table.concat(missingModules, "\n - "), 0) end
| |
| 32 | ||
| 33 | -- Wrap neural link as a peripheral, clear the old canvas and create a new one | |
| 34 | local link = peripheral.wrap("back")
| |
| 35 | link.canvas3d().clear() | |
| 36 | local canvas = link.canvas3d().create() | |
| 37 | ||
| 38 | -- How many seconds there are between scans | |
| 39 | local TIME_BETWEEN_SCANS = 0 | |
| 40 | ||
| 41 | -- Set to true if you want to disable configuration screen and always use all ores | |
| 42 | local NO_CONFIGURATION_UI = false | |
| 43 | ||
| 44 | -- The color values used in the background colors, can be found here: http://computercraft.info/wiki/Colors_(API) | |
| 45 | -- CHANGE THESE IF YOU HAVE DEUTERANOPIA AND CANNOT EASILY DIFFERENTIATE RED AND GREEN | |
| 46 | local COLOR_BLACK = 32768 | |
| 47 | local COLOR_RED = 16384 | |
| 48 | local COLOR_GREEN = 32 | |
| 49 | ||
| 50 | -- Get screen size to draw UI properly | |
| 51 | local x = term.getSize() | |
| 52 | ||
| 53 | -- List of ores that are tracked, will be all if NO_CONFIGURATION_UI is set to true | |
| 54 | local ores = {}
| |
| 55 | ||
| 56 | -- List of all ores this tracker can track with current settings in current modpack | |
| 57 | local completeOreList = {
| |
| 58 | "minecraft:coal_ore", | |
| 59 | "minecraft:deepslate_coal_ore", | |
| 60 | "minecraft:iron_ore", | |
| 61 | "minecraft:deepslate_iron_ore", | |
| 62 | "minecraft:redstone_ore", | |
| 63 | "minecraft:deepslate_redstone_ore", | |
| 64 | "minecraft:gold_ore", | |
| 65 | "minecraft:deepslate_gold_ore", | |
| 66 | "minecraft:lapis_ore", | |
| 67 | "minecraft:deepslate_lapis_ore", | |
| 68 | "minecraft:diamond_ore", | |
| 69 | "minecraft:deepslate_diamond_ore", | |
| 70 | "minecraft:emerald_ore", | |
| 71 | "minecraft:deepslate_emerald_ore", | |
| 72 | "minecraft:copper_ore", | |
| 73 | "minecraft:deepslate_copper_ore", | |
| 74 | "minecraft:nether_quartz_ore", | |
| 75 | "minecraft:ancient_debris", | |
| 76 | } | |
| 77 | ||
| 78 | -- This table hold selected ores | |
| 79 | local _UI_CONFIG = {}
| |
| 80 | ||
| 81 | -- Colors for ore tracers, colors use HEX with alpha, these can be changed | |
| 82 | local colors = {
| |
| 83 | ["minecraft:coal_ore"] = 0x000000ff, | |
| 84 | ["minecraft:deepslate_coal_ore"] = 0x000000ff, | |
| 85 | ["minecraft:iron_ore"] = 0xff9632ff, | |
| 86 | ["minecraft:deepslate_iron_ore"] = 0xff9632ff, | |
| 87 | ["minecraft:redstone_ore"] = 0xff0000ff, | |
| 88 | ["minecraft:deepslate_redstone_ore"] = 0xff0000ff, | |
| 89 | ["minecraft:gold_ore"] = 0xffff00ff, | |
| 90 | ["minecraft:deepslate_gold_ore"] = 0xffff00ff, | |
| 91 | ["minecraft:lapis_ore"] = 0x0032ffff, | |
| 92 | ["minecraft:deepslate_lapis_ore"] = 0x0032ffff, | |
| 93 | ["minecraft:diamond_ore"] = 0x00ffffff, | |
| 94 | ["minecraft:deepslate_diamond_ore"] = 0x00ffffff, | |
| 95 | ["minecraft:emerald_ore"] = 0x00ff00ff, | |
| 96 | ["minecraft:deepslate_emerald_ore"] = 0x00ff00ff, | |
| 97 | ["minecraft:copper_ore"] = 0x00996633, | |
| 98 | ["minecraft:deepslate_copper_ore"] = 0x00996633, | |
| 99 | ["minecraft:nether_quartz_ore"] = 0x00CCCCCC, | |
| 100 | ["minecraft:ancient_debris"] = 0x00FFCC99, | |
| 101 | } | |
| 102 | ||
| 103 | -- This function renders a line for all given blocks with given attributes | |
| 104 | function renderLines(vectorList) | |
| 105 | -- Clear the 3D canvas so lines don't stack up | |
| 106 | link.canvas3d().clear() | |
| 107 | ||
| 108 | -- Create a new canvas, since link.canvas3d().clear() dereferences it | |
| 109 | local canvas = link.canvas3d().create() | |
| 110 | ||
| 111 | -- Loop through all given objects and draw lines to all of them with given thickness and color | |
| 112 | for i = 1, #vectorList, 1 do | |
| 113 | canvas.addLine({ 0, -1, 0 }, { vectorList[i].x, vectorList[i].y, vectorList[i].z }, vectorList[i].thickness, vectorList[i].color)
| |
| 114 | end | |
| 115 | end | |
| 116 | ||
| 117 | -- Starting UI to select wanted ores | |
| 118 | while not NO_CONFIGURATION_UI do | |
| 119 | -- Clear the screen and write ores onto it | |
| 120 | term.setBackgroundColor(COLOR_BLACK) | |
| 121 | term.clear() | |
| 122 | ||
| 123 | -- Loop through all the available ores to write them to screen in a specific order | |
| 124 | for i = 1, #completeOreList, 1 do | |
| 125 | -- Variable for checking if ore exists in list of selected ores | |
| 126 | local isSelected = false | |
| 127 | ||
| 128 | -- Move the cursor to the appropriate line | |
| 129 | term.setCursorPos(1, i) | |
| 130 | ||
| 131 | -- Calculate how many spaces are needed to center the text in the window | |
| 132 | local spaces = string.rep(" ", math.floor((x - (#completeOreList[i] + 2)) / 2))
| |
| 133 | ||
| 134 | -- Make the string to print on the screen | |
| 135 | local str = "[" .. spaces .. completeOreList[i] .. spaces | |
| 136 | ||
| 137 | if (#str + 1 < x) then str = str .. " ]" | |
| 138 | else str = str .. "]" end | |
| 139 | ||
| 140 | -- If the ore can be found from the list of selected, make isSelected true, otherwise false | |
| 141 | for j = 1, #_UI_CONFIG, 1 do | |
| 142 | if (_UI_CONFIG[j] == completeOreList[i]) then isSelected = true end | |
| 143 | end | |
| 144 | ||
| 145 | -- If the ore is selected, make its background green, otherwise background is red | |
| 146 | if (isSelected) then | |
| 147 | term.setBackgroundColor(COLOR_GREEN) | |
| 148 | else | |
| 149 | term.setBackgroundColor(COLOR_RED) | |
| 150 | end | |
| 151 | ||
| 152 | -- Prints the ore name in the correct position | |
| 153 | print(str) | |
| 154 | end | |
| 155 | ||
| 156 | -- Set the cursor for second line below the ore block and set the text background to green | |
| 157 | term.setCursorPos(1, #completeOreList + 2) | |
| 158 | term.setBackgroundColor(COLOR_GREEN) | |
| 159 | ||
| 160 | -- Make string [ Start Application ] and center it on the line | |
| 161 | local str = "Start Application" | |
| 162 | ||
| 163 | -- This function replicates spaces until we get enough that the text is centered | |
| 164 | local spaces = string.rep(" ", math.floor((x - (#str + 2)) / 2))
| |
| 165 | local toPrint = "[" .. spaces .. str .. spaces | |
| 166 | ||
| 167 | -- If the amount of spaces is one too few, add one to the end | |
| 168 | if (#toPrint + 1 < x) then toPrint = toPrint .. " ]" | |
| 169 | else toPrint = toPrint .. "]" end | |
| 170 | ||
| 171 | -- Write the new string to the screen and turn the background back to black | |
| 172 | write(toPrint) | |
| 173 | term.setBackgroundColor(COLOR_BLACK) | |
| 174 | ||
| 175 | -- Check for mouse clicks | |
| 176 | local event, button, x, y = os.pullEvent("mouse_click")
| |
| 177 | ||
| 178 | -- If the mouse click is inside the area designated for ores, then log which ore was clicked | |
| 179 | if (y <= #completeOreList) then | |
| 180 | -- Variable for checking if ore already exists in table | |
| 181 | local isInTable = false | |
| 182 | ||
| 183 | -- Loop through all the selected ores to check if the clicked one is already selected | |
| 184 | for i = 1, #_UI_CONFIG, 1 do | |
| 185 | -- If ore is already selected, make isInTable its index, otherwise it stays false | |
| 186 | if (_UI_CONFIG[i] == completeOreList[y]) then isInTable = i end | |
| 187 | end | |
| 188 | ||
| 189 | -- If not false (AKA has an index) then remove that index from the table | |
| 190 | -- Otherwise insert value into the table | |
| 191 | if (isInTable ~= false) then | |
| 192 | table.remove(_UI_CONFIG, isInTable) | |
| 193 | else | |
| 194 | table.insert(_UI_CONFIG, completeOreList[y]) | |
| 195 | end | |
| 196 | else | |
| 197 | -- If the mouse click is outside of the ore selection area, then break and start the main application | |
| 198 | break | |
| 199 | end | |
| 200 | end | |
| 201 | ||
| 202 | ||
| 203 | -- Track all ores if NO_CONFIGURATION_UI is true and only selected if false | |
| 204 | if (NO_CONFIGURATION_UI) then | |
| 205 | ores = completeOreList | |
| 206 | else | |
| 207 | ores = _UI_CONFIG | |
| 208 | end | |
| 209 | ||
| 210 | -- Clear the canvas and set background color to black when starting | |
| 211 | -- Please ignore this code block, it looks terrible, but making it better is not worth the effort | |
| 212 | term.setBackgroundColor(COLOR_BLACK) | |
| 213 | canvas.clear() | |
| 214 | term.clear() | |
| 215 | term.setCursorPos(1,1) | |
| 216 | print("Hold CTRL + T to stop execution")
| |
| 217 | term.setCursorPos(1,2) | |
| 218 | print("Hold CTRL + R to reconfigure ores")
| |
| 219 | term.setCursorPos(1,4) | |
| 220 | print("Ores selected: " .. #ores)
| |
| 221 | term.setCursorPos(1,6) | |
| 222 | print("Code running...")
| |
| 223 | ||
| 224 | ||
| 225 | -- Main execution block where ore tracking and rendering happens | |
| 226 | while true do | |
| 227 | local oreList = {}
| |
| 228 | -- Block scanning | |
| 229 | for _, block in pairs(link.scan()) do | |
| 230 | -- Loop through all the ores that are being tracked | |
| 231 | for i = 1, #ores, 1 do | |
| 232 | -- If a matching ore is found, execute the following code | |
| 233 | if (block.name == ores[i]) then | |
| 234 | -- Create an object with all necessary parameters | |
| 235 | local toAdd = {
| |
| 236 | ["x"] = block.x, | |
| 237 | ["y"] = block.y, | |
| 238 | ["z"] = block.z, | |
| 239 | ["thickness"] = 3.0, | |
| 240 | ["color"] = colors[block.name] | |
| 241 | } | |
| 242 | -- Insert made object into a table before being sent to the renderer | |
| 243 | table.insert(oreList, toAdd) | |
| 244 | end | |
| 245 | end | |
| 246 | end | |
| 247 | ||
| 248 | -- Render lines with correct colors for all blocks and sleep (if time is set) | |
| 249 | renderLines(oreList) | |
| 250 | os.sleep(TIME_BETWEEN_SCANS) | |
| 251 | end |