UI-ification of the ores/xray app

This commit is contained in:
Anavrins
2020-08-13 21:18:49 -04:00
parent 287b362765
commit 153c1ac4a2

View File

@@ -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,38 +36,146 @@ 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 })
-(offset.z % 1) + .5 }
)
local function update()
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 = getPoint()
local pos = GPS.locate()
if pos then
if math.abs(pos.x - offset.x) +
@@ -81,7 +194,7 @@ local function update()
local blocks = { }
for _, b in pairs(scanned) do
if targets[b.name..(b.metadata ~= 0 and ":"..b.metadata or "")] then
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),
@@ -95,7 +208,7 @@ local function update()
if not projecting[b.id] then
projecting[b.id] = b
local target = targets[b.name..(b.metadata ~= 0 and ":"..b.metadata or "")]
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)
@@ -107,7 +220,7 @@ local function update()
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 = canvas.addItem({ x, y, z }, target[1], target[2], page.blockSize)
b.box.setDepthTested(false)
end
end
@@ -122,20 +235,10 @@ local function update()
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
)
UI:setPage(page)
UI:start()
canvas.clear()