UI-ification of the ores/xray app
This commit is contained in:
307
neural/ores.lua
307
neural/ores.lua
@@ -6,7 +6,12 @@
|
||||
-- Updated to use new(ish) canvas3d
|
||||
|
||||
local Config = require('opus.config')
|
||||
local GPS = require("opus.gps")
|
||||
local GPS = require('opus.gps')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
local itemDB = require('core.itemDB')
|
||||
local Event = require('opus.event')
|
||||
local Angle = require('neural.angle')
|
||||
|
||||
local keys = _G.keys
|
||||
local os = _G.os
|
||||
@@ -31,111 +36,209 @@ elseif not modules.scan then
|
||||
showRequirements('Scanner module')
|
||||
end
|
||||
|
||||
-- size of displayed block
|
||||
local BLOCK_SIZE = .5
|
||||
|
||||
local function getPoint()
|
||||
return GPS.locate()
|
||||
end
|
||||
|
||||
local targets = Config.load('ores', {
|
||||
["minecraft:emerald_ore"] = { "minecraft:emerald_ore", 0 },
|
||||
["minecraft:diamond_ore"] = { "minecraft:diamond_ore", 0 },
|
||||
["minecraft:gold_ore"] = { "minecraft:gold_ore", 0 },
|
||||
["minecraft:redstone_ore"] = { "minecraft:redstone_ore", 0 },
|
||||
["minecraft:lit_redstone_ore"] = { "minecraft:redstone_ore", 0 },
|
||||
["minecraft:iron_ore"] = { "minecraft:iron_ore", 0 },
|
||||
["minecraft:lapis_ore"] = { "minecraft:lapis_ore", 0 },
|
||||
["minecraft:coal_ore"] = { "minecraft:coal_ore", 0 },
|
||||
["minecraft:quartz_ore"] = { "minecraft:quartz_ore", 0 },
|
||||
["minecraft:glowstone"] = { "minecraft:glowstone", 0 },
|
||||
})
|
||||
|
||||
local projecting = { }
|
||||
local offset = getPoint() or showRequirements('GPS')
|
||||
local offset = GPS.locate() or showRequirements('GPS')
|
||||
local canvas = modules.canvas3d().create({
|
||||
-(offset.x % 1) + .5,
|
||||
-(offset.y % 1) + .5,
|
||||
-(offset.z % 1) + .5 })
|
||||
|
||||
local function update()
|
||||
while true do
|
||||
-- order matters
|
||||
local scanned = modules.scan()
|
||||
local pos = getPoint()
|
||||
|
||||
if pos then
|
||||
if math.abs(pos.x - offset.x) +
|
||||
math.abs(pos.y - offset.y) +
|
||||
math.abs(pos.z - offset.z) > 64 then
|
||||
for _, b in pairs(projecting) do
|
||||
b.box.remove()
|
||||
end
|
||||
projecting = { }
|
||||
offset = pos
|
||||
canvas.recenter({
|
||||
-(offset.x % 1) + .5,
|
||||
-(offset.y % 1) + .5,
|
||||
-(offset.z % 1) + .5 })
|
||||
end
|
||||
|
||||
local blocks = { }
|
||||
for _, b in pairs(scanned) do
|
||||
if targets[b.name..(b.metadata ~= 0 and ":"..b.metadata or "")] then
|
||||
-- track block's world position
|
||||
b.id = table.concat({
|
||||
math.floor(pos.x + b.x),
|
||||
math.floor(pos.y + b.y),
|
||||
math.floor(pos.z + b.z) }, ':')
|
||||
blocks[b.id] = b
|
||||
end
|
||||
end
|
||||
|
||||
for _, b in pairs(blocks) do
|
||||
if not projecting[b.id] then
|
||||
projecting[b.id] = b
|
||||
|
||||
local target = targets[b.name..(b.metadata ~= 0 and ":"..b.metadata or "")]
|
||||
|
||||
local x = b.x - math.floor(offset.x) + math.floor(pos.x)
|
||||
local y = b.y - math.floor(offset.y) + math.floor(pos.y)
|
||||
local z = b.z - math.floor(offset.z) + math.floor(pos.z)
|
||||
|
||||
--[[
|
||||
b.box = canvas.addFrame({ x, y, z })
|
||||
b.box.setDepthTested(false)
|
||||
b.box.addItem({ .25, .25 }, target[1], target[2], 2)
|
||||
--]]
|
||||
|
||||
b.box = canvas.addItem({ x, y, z }, target[1], target[2], BLOCK_SIZE)
|
||||
b.box.setDepthTested(false)
|
||||
end
|
||||
end
|
||||
|
||||
for _, b in pairs(projecting) do
|
||||
if not blocks[b.id] then
|
||||
b.box.remove()
|
||||
projecting[b.id] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
os.sleep(.5)
|
||||
end
|
||||
end
|
||||
|
||||
parallel.waitForAny(
|
||||
function()
|
||||
print('Ore visualization started')
|
||||
print('Press enter to exit')
|
||||
while true do
|
||||
local e, key = os.pullEventRaw('key')
|
||||
if key == keys.enter or e == 'terminate' then
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
update
|
||||
-(offset.z % 1) + .5 }
|
||||
)
|
||||
|
||||
local page = UI.Page {
|
||||
notification = UI.Notification {},
|
||||
|
||||
menuBar = UI.MenuBar {
|
||||
buttons = {
|
||||
{ text = 'Scan', event = 'scan' },
|
||||
{ text = 'Size', event = 'size' },
|
||||
-- { text = 'Laser', event = 'laser' }, -- If you dare
|
||||
}
|
||||
},
|
||||
|
||||
sizeSlide = UI.MiniSlideOut {
|
||||
x = -13,
|
||||
sizeEntry = UI.TextEntry {
|
||||
shadowText = "Block Size",
|
||||
accelerators = {enter = 'size_accept'}
|
||||
}
|
||||
},
|
||||
|
||||
grid = UI.CheckboxGrid {
|
||||
y = 2,
|
||||
columns = {
|
||||
{ heading = 'Count', key = 'count', width = 6, align = 'right' },
|
||||
{ heading = 'Name', key = 'displayName' },
|
||||
},
|
||||
sortColumn = 'displayName',
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function page:scan()
|
||||
local rawBlocks = modules.scan()
|
||||
self.totals = Util.reduce(rawBlocks, function(acc, b)
|
||||
if b.name == 'minecraft:air' then return acc end
|
||||
b.key = table.concat({ b.name, b.metadata }, ':')
|
||||
local entry = acc[b.key]
|
||||
if not entry then
|
||||
b.displayName = itemDB:getName(b.key)
|
||||
b.count = 1
|
||||
acc[b.key] = b
|
||||
else
|
||||
entry.count = entry.count + 1
|
||||
end
|
||||
|
||||
return acc
|
||||
end,
|
||||
Util.reduce(self.targets, function(acc, b)
|
||||
local key = table.concat({ b[1], b[2] }, ':')
|
||||
acc[key] = {
|
||||
displayName = itemDB:getName(key),
|
||||
name = b[1],
|
||||
metadata = b[2],
|
||||
key = key,
|
||||
count = 0,
|
||||
checked = true,
|
||||
}
|
||||
return acc
|
||||
end, { })
|
||||
)
|
||||
self.grid:setValues(self.totals)
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function page:shootLaser()
|
||||
if not modules.fire then self.notification:error("No laser found") return end
|
||||
self.notification:info("Shooting...")
|
||||
self:sync()
|
||||
local targets = Util.filter(modules.scan(), function(b)
|
||||
return self.targets[table.concat({ b.name, b.metadata }, ':')]
|
||||
end)
|
||||
|
||||
Util.each(targets, function(b)
|
||||
local yaw, pitch = Angle.towards(b.x, b.y, b.z)
|
||||
if pitch < 40 then -- Avoid shooting the block below you
|
||||
modules.fire(yaw, pitch, 3)
|
||||
end
|
||||
end)
|
||||
self.notification:success("Done!")
|
||||
end
|
||||
|
||||
function page:loadConfigs()
|
||||
self.blockSize, self.targets = unpack(Config.load('ores', {.5, {}}))
|
||||
end
|
||||
|
||||
function page:saveConfigs()
|
||||
Config.update('ores', {self.blockSize, self.targets})
|
||||
end
|
||||
|
||||
function page.grid:getRowTextColor(row, selected)
|
||||
return row.checked and colors.yellow or UI.CheckboxGrid.getRowTextColor(self, row, selected)
|
||||
end
|
||||
|
||||
function page:eventHandler(event)
|
||||
if event.type == "scan" then
|
||||
self.notification:info("Scanning...")
|
||||
self:sync()
|
||||
self:scan()
|
||||
self.notification:success("Done!")
|
||||
elseif event.type == "size" then
|
||||
self.sizeSlide:show()
|
||||
elseif event.type == "size_accept" then
|
||||
self.blockSize = tonumber(self.sizeSlide.sizeEntry.value) or self.blockSize
|
||||
self.blockSize = math.max(self.blockSize, 0)
|
||||
self.sizeSlide.sizeEntry:reset()
|
||||
self.sizeSlide:hide()
|
||||
|
||||
elseif event.type == "laser" then
|
||||
self:shootLaser()
|
||||
|
||||
elseif event.type == "grid_select" then
|
||||
local block = event.selected
|
||||
local key = table.concat({ block.name, block.metadata }, ':')
|
||||
if block.checked then
|
||||
self.targets[key] = {block.name, block.metadata}
|
||||
else
|
||||
self.targets[key] = nil
|
||||
end
|
||||
page:saveConfigs()
|
||||
else return UI.Page.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
page:loadConfigs()
|
||||
page:scan()
|
||||
|
||||
Event.addRoutine(
|
||||
function()
|
||||
while true do
|
||||
-- order matters
|
||||
local scanned = modules.scan()
|
||||
local pos = GPS.locate()
|
||||
|
||||
if pos then
|
||||
if math.abs(pos.x - offset.x) +
|
||||
math.abs(pos.y - offset.y) +
|
||||
math.abs(pos.z - offset.z) > 64 then
|
||||
for _, b in pairs(projecting) do
|
||||
b.box.remove()
|
||||
end
|
||||
projecting = { }
|
||||
offset = pos
|
||||
canvas.recenter({
|
||||
-(offset.x % 1) + .5,
|
||||
-(offset.y % 1) + .5,
|
||||
-(offset.z % 1) + .5 })
|
||||
end
|
||||
|
||||
local blocks = { }
|
||||
for _, b in pairs(scanned) do
|
||||
if page.targets[table.concat({b.name, b.metadata or 0}, ":")] then
|
||||
-- track block's world position
|
||||
b.id = table.concat({
|
||||
math.floor(pos.x + b.x),
|
||||
math.floor(pos.y + b.y),
|
||||
math.floor(pos.z + b.z) }, ':')
|
||||
blocks[b.id] = b
|
||||
end
|
||||
end
|
||||
|
||||
for _, b in pairs(blocks) do
|
||||
if not projecting[b.id] then
|
||||
projecting[b.id] = b
|
||||
|
||||
local target = page.targets[table.concat({b.name, b.metadata or 0}, ":")]
|
||||
|
||||
local x = b.x - math.floor(offset.x) + math.floor(pos.x)
|
||||
local y = b.y - math.floor(offset.y) + math.floor(pos.y)
|
||||
local z = b.z - math.floor(offset.z) + math.floor(pos.z)
|
||||
|
||||
--[[
|
||||
b.box = canvas.addFrame({ x, y, z })
|
||||
b.box.setDepthTested(false)
|
||||
b.box.addItem({ .25, .25 }, target[1], target[2], 2)
|
||||
--]]
|
||||
|
||||
b.box = canvas.addItem({ x, y, z }, target[1], target[2], page.blockSize)
|
||||
b.box.setDepthTested(false)
|
||||
end
|
||||
end
|
||||
|
||||
for _, b in pairs(projecting) do
|
||||
if not blocks[b.id] then
|
||||
b.box.remove()
|
||||
projecting[b.id] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
os.sleep(.5)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
UI:setPage(page)
|
||||
UI:start()
|
||||
|
||||
canvas.clear()
|
||||
|
||||
Reference in New Issue
Block a user