Advertisement
toastonrye

Ore Scanner 1.12.2 Example

Jul 24th, 2022
900
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.78 KB | None | 0 0
  1. --- This renders a minimap showing nearby ores using the overlay glasses and block scanner.
  2.  
  3. --- We start the program by specifying a series of configuration options. Feel free to ignore these, and use the values
  4. --- inline. Whilst you don't strictly speaking need a delay between each iteration, it does reduce the impact on the
  5. --- server.
  6. local scanInterval = 0.2
  7. local renderInterval = 0.05
  8. local scannerRange = 8
  9. local scannerWidth = scannerRange * 2 + 1
  10.  
  11. --- These values aren't very exciting, they just control what the minimap looks like
  12. local size = 0.5
  13. local cellSize = 16
  14. local offsetX = 75
  15. local offsetY = 75
  16.  
  17. --- We end our configuration section by defining the ores we're interested in and what colour we'll draw them as. We
  18. --- define some ores as having a higher priority, so large ore veins don't mask smaller veins of more precious ores.
  19. local ores = {
  20.     ["minecraft:diamond_ore"] = 10,
  21.     ["minecraft:emerald_ore"] = 10,
  22.     ["minecraft:gold_ore"] = 8,
  23.     ["minecraft:redstone_ore"] = 5,
  24.     ["minecraft:lapis_ore"] = 5,
  25.     ["minecraft:iron_ore"] = 2,
  26.     ["minecraft:coal_ore"] = 1
  27. }
  28.  
  29. local colours = {
  30.     ["minecraft:coal_ore"] = { 150, 150, 150 },
  31.     ["minecraft:iron_ore"] = { 255, 150, 50 },
  32.     ["minecraft:lava"] = { 150, 75, 0 },
  33.     ["minecraft:gold_ore"] = { 255, 255, 0 },
  34.     ["minecraft:diamond_ore"] = { 0, 255, 255 },
  35.     ["minecraft:redstone_ore"] = { 255, 0, 0 },
  36.     ["minecraft:lapis_ore"] = { 0, 50, 255 },
  37.     ["minecraft:emerald_ore"] = { 0, 255, 0 }
  38. }
  39.  
  40. --- Now let's get into the interesting stuff! Let's look for a neural interface and check we've got all the required
  41. --- modules.
  42. local modules = peripheral.find("neuralInterface")
  43. if not modules then error("Must have a neural interface", 0) end
  44. if not modules.hasModule("plethora:scanner") then error("The block scanner is missing", 0) end
  45. if not modules.hasModule("plethora:glasses") then error("The overlay glasses are missing", 0) end
  46.  
  47. --- Now we've got our neural interface, let's extract the canvas and ensure nothing else is on it.
  48. local canvas = modules.canvas()
  49. canvas.clear()
  50.  
  51. --- We now need to set up our minimap. We create a 2D array of text objects around the player, each starting off
  52. --- displaying an empty string. If we find an ore, we'll update their colour and text.
  53. local block_text = {}
  54. local blocks = {}
  55. for x = -scannerRange, scannerRange, 1 do
  56.     block_text[x] = {}
  57.     blocks[x] = {}
  58.  
  59.     for z = -scannerRange, scannerRange, 1 do
  60.         block_text[x][z] = canvas.addText({ 0, 0 }, " ", 0xFFFFFFFF, size)
  61.         blocks[x][z] = { y = nil, block = nil }
  62.     end
  63. end
  64.  
  65. --- We also create a marker showing the current player's location.
  66. canvas.addText({ offsetX, offsetY }, "^", 0xFFFFFFFF, size * 2)
  67.  
  68. --- Our first big function is the scanner: this searches for ores near the player, finds the most important ones, and
  69. --- updates the block table.
  70. local function scan()
  71.     while true do
  72.         local scanned_blocks = modules.scan()
  73.  
  74.         --- For each nearby position, we search the y axis for interesting ores. We look for the one which has
  75.         --- the highest priority and update the block information
  76.         for x = -scannerRange, scannerRange do
  77.             for z = -scannerRange, scannerRange do
  78.                 local best_score, best_block, best_y = -1
  79.                 for y = -scannerRange, scannerRange do
  80.                     --- The block scanner returns blocks in a flat array, so we index into it with this rather scary formulae.
  81.                     local scanned = scanned_blocks[scannerWidth ^ 2 * (x + scannerRange) + scannerWidth * (y + scannerRange) + (z + scannerRange) + 1]
  82.  
  83.                     --- If there is a block here, and it's more interesting than our previous ores, then let's use that!
  84.                     if scanned then
  85.                         local new_score = ores[scanned.name]
  86.                         if new_score and new_score > best_score then
  87.                             best_block = scanned.name
  88.                             best_score = new_score
  89.                             best_y = y
  90.                         end
  91.                     end
  92.                 end
  93.  
  94.                 -- Update our block table with this information.
  95.                 blocks[x][z].block = best_block
  96.                 blocks[x][z].y = best_y
  97.             end
  98.         end
  99.  
  100.         --- We wait for some delay before starting again. This isn't _strictly_ needed, but helps reduce server load
  101.         sleep(scanInterval)
  102.     end
  103. end
  104.  
  105. --- The render function takes our block information generated in the previous function and updates the text elements.
  106. local function render()
  107.     while true do
  108.         --- If possible, we rotate the map using the current player's look direction. If it's not available, we'll just
  109.         --- use north as up.
  110.         local meta = modules.getMetaOwner and modules.getMetaOwner()
  111.         local angle = meta and math.rad(-meta.yaw % 360) or math.rad(180)
  112.  
  113.         --- Like before, loop over every nearby block and update something. Though this time we're updating objects on
  114.         --- the overlay canvas.
  115.         for x = -scannerRange, scannerRange do
  116.             for z = -scannerRange, scannerRange do
  117.                 local text = block_text[x][z]
  118.                 local block = blocks[x][z]
  119.  
  120.                 if block.block then
  121.                     --- If we've got a block here, we update the position of our text element to account for rotation,
  122.                     local px = math.cos(angle) * -x - math.sin(angle) * -z
  123.                     local py = math.sin(angle) * -x + math.cos(angle) * -z
  124.  
  125.                     local sx = math.floor(px * size * cellSize)
  126.                     local sy = math.floor(py * size * cellSize)
  127.                     text.setPosition(offsetX + sx, offsetY + sy)
  128.  
  129.                     --- Then change the text and colour to match the location of the ore
  130.                     text.setText(tostring(block.y))
  131.                     text.setColor(table.unpack(colours[block.block]))
  132.                 else
  133.                     --- Otherwise we just make sure the text is empty. We don't need to faff about with clearing the
  134.                     --- colour or position, as we'll change it next iteration anyway.
  135.                     text.setText(" ")
  136.                 end
  137.             end
  138.         end
  139.  
  140.         sleep(renderInterval)
  141.     end
  142. end
  143.  
  144. --- We now run our render and scan loops in parallel, continually updating our block list and redisplaying it to the
  145. --- wearer.
  146. parallel.waitForAll(render, scan)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement