· 4 years ago · Jan 20, 2021, 03:30 AM
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
20local modules = peripheral.find("neuralInterface")
21if not modules then error("must have a neural interface", 0) end
22
23-- List so we can display all missing modules at once
24local missingModules = {}
25
26-- Checks the existence of necessary modules
27if not modules.hasModule("plethora:scanner") then table.insert(missingModules, "Block Scanner") end
28if not modules.hasModule("plethora:glasses") then table.insert(missingModules, "Overlay Glasses") end
29
30-- If one or more modules are missing, error out
31if (#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
34local link = peripheral.wrap("back")
35link.canvas3d().clear()
36local canvas = link.canvas3d().create()
37
38-- How many seconds there are between scans
39local TIME_BETWEEN_SCANS = 0
40
41-- Set to true if you want to disable configuration screen and always use all ores
42local 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
46local COLOR_BLACK = 32768
47local COLOR_RED = 16384
48local COLOR_GREEN = 32
49
50-- Get screen size to draw UI properly
51local x = term.getSize()
52
53-- List of ores that are tracked, will be all if NO_CONFIGURATION_UI is set to true
54local ores = {}
55
56-- List of all ores this tracker can track with current settings in current modpack
57local completeOreList = {
58 "minecraft:coal_ore",
59 "minecraft:iron_ore",
60 "minecraft:redstone_ore",
61 "minecraft:gold_ore",
62 "minecraft:lapis_ore",
63 "minecraft:diamond_ore",
64 "minecraft:emerald_ore",
65 "ic2:resource",
66 "appliedenergistics2:quartz_ore",
67 "thermalfoundation:ore_fluid"
68}
69
70-- This table hold selected ores
71local _UI_CONFIG = {}
72
73-- Colors for ore tracers, colors use HEX with alpha, these can be changed
74local colors = {
75 ["minecraft:coal_ore"] = 0x000000ff,
76 ["minecraft:iron_ore"] = 0xff9632ff,
77 ["minecraft:redstone_ore"] = 0xff0000ff,
78 ["minecraft:gold_ore"] = 0xffff00ff,
79 ["minecraft:lapis_ore"] = 0x0032ffff,
80 ["minecraft:diamond_ore"] = 0x00ffffff,
81 ["minecraft:emerald_ore"] = 0x00ff00ff,
82 ["ic2:resource"] = 0x005a00ff,
83 ["appliedenergistics2:quartz_ore"] = 0xe3fcfaff,
84 ["thermalfoundation:ore_fluid"] = 0x781725ff
85}
86
87-- This function renders a line for all given blocks with given attributes
88function renderLines(vectorList)
89 -- Clear the 3D canvas so lines don't stack up
90 link.canvas3d().clear()
91
92 -- Create a new canvas, since link.canvas3d().clear() dereferences it
93 local canvas = link.canvas3d().create()
94
95 -- Loop through all given objects and draw lines to all of them with given thickness and color
96 for i = 1, #vectorList, 1 do
97 canvas.addLine({ 0, -1, 0 }, { vectorList[i].x, vectorList[i].y, vectorList[i].z }, vectorList[i].thickness, vectorList[i].color)
98 end
99end
100
101-- Starting UI to select wanted ores
102while not NO_CONFIGURATION_UI do
103 -- Clear the screen and write ores onto it
104 term.setBackgroundColor(COLOR_BLACK)
105 term.clear()
106
107 -- Loop through all the available ores to write them to screen in a specific order
108 for i = 1, #completeOreList, 1 do
109 -- Variable for checking if ore exists in list of selected ores
110 local isSelected = false
111
112 -- Move the cursor to the appropriate line
113 term.setCursorPos(1, i)
114
115 -- Calculate how many spaces are needed to center the text in the window
116 local spaces = string.rep(" ", math.floor((x - (#completeOreList[i] + 2)) / 2))
117
118 -- Make the string to print on the screen
119 local str = "[" .. spaces .. completeOreList[i] .. spaces
120
121 if (#str + 1 < x) then str = str .. " ]"
122 else str = str .. "]" end
123
124 -- If the ore can be found from the list of selected, make isSelected true, otherwise false
125 for j = 1, #_UI_CONFIG, 1 do
126 if (_UI_CONFIG[j] == completeOreList[i]) then isSelected = true end
127 end
128
129 -- If the ore is selected, make its background green, otherwise background is red
130 if (isSelected) then
131 term.setBackgroundColor(COLOR_GREEN)
132 else
133 term.setBackgroundColor(COLOR_RED)
134 end
135
136 -- Prints the ore name in the correct position
137 print(str)
138 end
139
140 -- Set the cursor for second line below the ore block and set the text background to green
141 term.setCursorPos(1, #completeOreList + 2)
142 term.setBackgroundColor(COLOR_GREEN)
143
144 -- Make string [ Start Application ] and center it on the line
145 local str = "Start Application"
146
147 -- This function replicates spaces until we get enough that the text is centered
148 local spaces = string.rep(" ", math.floor((x - (#str + 2)) / 2))
149 local toPrint = "[" .. spaces .. str .. spaces
150
151 -- If the amount of spaces is one too few, add one to the end
152 if (#toPrint + 1 < x) then toPrint = toPrint .. " ]"
153 else toPrint = toPrint .. "]" end
154
155 -- Write the new string to the screen and turn the background back to black
156 write(toPrint)
157 term.setBackgroundColor(COLOR_BLACK)
158
159 -- Check for mouse clicks
160 local event, button, x, y = os.pullEvent("mouse_click")
161
162 -- If the mouse click is inside the area designated for ores, then log which ore was clicked
163 if (y <= #completeOreList) then
164 -- Variable for checking if ore already exists in table
165 local isInTable = false
166
167 -- Loop through all the selected ores to check if the clicked one is already selected
168 for i = 1, #_UI_CONFIG, 1 do
169 -- If ore is already selected, make isInTable its index, otherwise it stays false
170 if (_UI_CONFIG[i] == completeOreList[y]) then isInTable = i end
171 end
172
173 -- If not false (AKA has an index) then remove that index from the table
174 -- Otherwise insert value into the table
175 if (isInTable ~= false) then
176 table.remove(_UI_CONFIG, isInTable)
177 else
178 table.insert(_UI_CONFIG, completeOreList[y])
179 end
180 else
181 -- If the mouse click is outside of the ore selection area, then break and start the main application
182 break
183 end
184end
185
186
187-- Track all ores if NO_CONFIGURATION_UI is true and only selected if false
188if (NO_CONFIGURATION_UI) then
189 ores = completeOreList
190else
191 ores = _UI_CONFIG
192end
193
194-- Clear the canvas and set background color to black when starting
195-- Please ignore this code block, it looks terrible, but making it better is not worth the effort
196term.setBackgroundColor(COLOR_BLACK)
197canvas.clear()
198term.clear()
199term.setCursorPos(1,1)
200print("Hold CTRL + T to stop execution")
201term.setCursorPos(1,2)
202print("Hold CTRL + R to reconfigure ores")
203term.setCursorPos(1,4)
204print("Ores selected: " .. #ores)
205term.setCursorPos(1,6)
206print("Code running...")
207
208
209-- Main execution block where ore tracking and rendering happens
210while true do
211 local oreList = {}
212 -- Block scanning
213 for _, block in pairs(link.scan()) do
214 -- Loop through all the ores that are being tracked
215 for i = 1, #ores, 1 do
216 -- If a matching ore is found, execute the following code
217 if (block.name == ores[i]) then
218 -- Create an object with all necessary parameters
219 local toAdd = {
220 ["x"] = block.x,
221 ["y"] = block.y,
222 ["z"] = block.z,
223 ["thickness"] = 3.0,
224 ["color"] = colors[block.name]
225 }
226 -- Insert made object into a table before being sent to the renderer
227 table.insert(oreList, toAdd)
228 end
229 end
230 end
231
232 -- Render lines with correct colors for all blocks and sleep (if time is set)
233 renderLines(oreList)
234 os.sleep(TIME_BETWEEN_SCANS)
235end