Add more
This commit is contained in:
parent
89a15d277f
commit
f7bb6c8137
5 changed files with 1055 additions and 0 deletions
150
scanner.lua
Normal file
150
scanner.lua
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
--- This renders a minimap showing nearby ores using the overlay glasses and block scanner.
|
||||
|
||||
--- We start the program by specifying a series of configuration options. Feel free to ignore these, and use the values
|
||||
--- inline. Whilst you don't strictly speaking need a delay between each iteration, it does reduce the impact on the
|
||||
--- server.
|
||||
local scanInterval = 0.2
|
||||
local renderInterval = 0.05
|
||||
local scannerRange = 8
|
||||
local scannerWidth = scannerRange * 2 + 1
|
||||
|
||||
--- These values aren't very exciting, they just control what the minimap looks like
|
||||
local size = 0.5
|
||||
local cellSize = 16
|
||||
local offsetX = 75
|
||||
local offsetY = 75
|
||||
|
||||
--- We end our configuration section by defining the ores we're interested in and what colour we'll draw them as. We
|
||||
--- define some ores as having a higher priority, so large ore veins don't mask smaller veins of more precious ores.
|
||||
local ores = {
|
||||
["minecraft:ancient_debris"] = 20,
|
||||
["minecraft:diamond_ore"] = 10,
|
||||
["minecraft:emerald_ore"] = 10,
|
||||
["minecraft:gold_ore"] = 8,
|
||||
["minecraft:redstone_ore"] = 5,
|
||||
["minecraft:lapis_ore"] = 5,
|
||||
["minecraft:iron_ore"] = 2,
|
||||
--["minecraft:nether_quartz_ore"] = 2,
|
||||
["minecraft:coal_ore"] = 1
|
||||
}
|
||||
|
||||
local colours = {
|
||||
["minecraft:ancient_debris"] = { 255,255,255 },
|
||||
--["minecraft:nether_quartz_ore"] = { 255, 255, 255 },
|
||||
["minecraft:coal_ore"] = { 150, 150, 150 },
|
||||
["minecraft:iron_ore"] = { 255, 150, 50 },
|
||||
["minecraft:lava"] = { 150, 75, 0 },
|
||||
["minecraft:gold_ore"] = { 255, 255, 0 },
|
||||
["minecraft:diamond_ore"] = { 0, 255, 255 },
|
||||
["minecraft:redstone_ore"] = { 255, 0, 0 },
|
||||
["minecraft:lapis_ore"] = { 0, 50, 255 },
|
||||
["minecraft:emerald_ore"] = { 0, 255, 0 }
|
||||
}
|
||||
|
||||
--- Now let's get into the interesting stuff! Let's look for a neural interface and check we've got all the required
|
||||
--- modules.
|
||||
local modules = peripheral.find("neuralInterface")
|
||||
if not modules then error("Must have a neural interface", 0) end
|
||||
if not modules.hasModule("plethora:scanner") then error("The block scanner is missing", 0) end
|
||||
if not modules.hasModule("plethora:glasses") then error("The overlay glasses are missing", 0) end
|
||||
|
||||
--- Now we've got our neural interface, let's extract the canvas and ensure nothing else is on it.
|
||||
local canvas = modules.canvas()
|
||||
canvas.clear()
|
||||
|
||||
--- We now need to set up our minimap. We create a 2D array of text objects around the player, each starting off
|
||||
--- displaying an empty string. If we find an ore, we'll update their colour and text.
|
||||
local block_text = {}
|
||||
local blocks = {}
|
||||
for x = -scannerRange, scannerRange, 1 do
|
||||
block_text[x] = {}
|
||||
blocks[x] = {}
|
||||
|
||||
for z = -scannerRange, scannerRange, 1 do
|
||||
block_text[x][z] = canvas.addText({ 0, 0 }, " ", 0xFFFFFFFF, size)
|
||||
blocks[x][z] = { y = nil, block = nil }
|
||||
end
|
||||
end
|
||||
|
||||
--- We also create a marker showing the current player's location.
|
||||
canvas.addText({ offsetX, offsetY }, "^", 0xFFFFFFFF, size * 2)
|
||||
|
||||
--- Our first big function is the scanner: this searches for ores near the player, finds the most important ones, and
|
||||
--- updates the block table.
|
||||
local function scan()
|
||||
while true do
|
||||
local scanned_blocks = modules.scan()
|
||||
|
||||
--- For each nearby position, we search the y axis for interesting ores. We look for the one which has
|
||||
--- the highest priority and update the block information
|
||||
for x = -scannerRange, scannerRange do
|
||||
for z = -scannerRange, scannerRange do
|
||||
local best_score, best_block, best_y = -1
|
||||
for y = -scannerRange, scannerRange do
|
||||
--- The block scanner returns blocks in a flat array, so we index into it with this rather scary formulae.
|
||||
local scanned = scanned_blocks[scannerWidth ^ 2 * (x + scannerRange) + scannerWidth * (y + scannerRange) + (z + scannerRange) + 1]
|
||||
|
||||
--- If there is a block here, and it's more interesting than our previous ores, then let's use that!
|
||||
if scanned then
|
||||
local new_score = ores[scanned.name]
|
||||
if new_score and new_score > best_score then
|
||||
best_block = scanned.name
|
||||
best_score = new_score
|
||||
best_y = y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update our block table with this information.
|
||||
blocks[x][z].block = best_block
|
||||
blocks[x][z].y = best_y
|
||||
end
|
||||
end
|
||||
|
||||
--- We wait for some delay before starting again. This isn't _strictly_ needed, but helps reduce server load
|
||||
sleep(scanInterval)
|
||||
end
|
||||
end
|
||||
|
||||
--- The render function takes our block information generated in the previous function and updates the text elements.
|
||||
local function render()
|
||||
while true do
|
||||
--- If possible, we rotate the map using the current player's look direction. If it's not available, we'll just
|
||||
--- use north as up.
|
||||
local meta = modules.getMetaOwner and modules.getMetaOwner()
|
||||
local angle = meta and math.rad(-meta.yaw % 360) or math.rad(180)
|
||||
|
||||
--- Like before, loop over every nearby block and update something. Though this time we're updating objects on
|
||||
--- the overlay canvas.
|
||||
for x = -scannerRange, scannerRange do
|
||||
for z = -scannerRange, scannerRange do
|
||||
local text = block_text[x][z]
|
||||
local block = blocks[x][z]
|
||||
|
||||
if block.block then
|
||||
--- If we've got a block here, we update the position of our text element to account for rotation,
|
||||
local px = math.cos(angle) * -x - math.sin(angle) * -z
|
||||
local py = math.sin(angle) * -x + math.cos(angle) * -z
|
||||
|
||||
local sx = math.floor(px * size * cellSize)
|
||||
local sy = math.floor(py * size * cellSize)
|
||||
text.setPosition(offsetX + sx, offsetY + sy)
|
||||
|
||||
--- Then change the text and colour to match the location of the ore
|
||||
text.setText(tostring(block.y))
|
||||
text.setColor(table.unpack(colours[block.block]))
|
||||
else
|
||||
--- Otherwise we just make sure the text is empty. We don't need to faff about with clearing the
|
||||
--- colour or position, as we'll change it next iteration anyway.
|
||||
text.setText(" ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sleep(renderInterval)
|
||||
end
|
||||
end
|
||||
|
||||
--- We now run our render and scan loops in parallel, continually updating our block list and redisplaying it to the
|
||||
--- wearer.
|
||||
parallel.waitForAll(render, scan)
|
||||
Loading…
Add table
Add a link
Reference in a new issue