Last active
January 3, 2019 03:20
-
-
Save mbainter/fad2d34cbf8943d7416857d5bc3026f4 to your computer and use it in GitHub Desktop.
drone-drawers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local range = 32 | |
local function proxyFor(name, required) | |
local address = component and component.list(name)() | |
if not address and required then | |
error("missing component '" .. name .. "'") | |
end | |
return address and component.proxy(address) or nil | |
end | |
local drone = proxyFor("drone", true) | |
local nav = proxyFor("navigation", true) | |
local invctrl = proxyFor("inventory_controller") | |
-- Colors used to indicate different states of operation. | |
local colorCharing = 0xFFCC33 | |
local colorSearching = 0x66CC66 | |
local colorDelivering = 0x6699FF | |
-- Keep track of our own position, relative to our starting position. | |
local px, py, pz = 0, 0, 0 | |
local function moveTo(x, y, z) | |
if type(x) == "table" then | |
x, y, z = x[1], x[2], x[3] | |
end | |
local rx, ry, rz = x - px, y - py, z - pz | |
drone.move(rx, ry, rz) | |
while drone.getOffset() > 0.5 or drone.getVelocity() > 0.5 do | |
computer.pullSignal(0.5) | |
end | |
px, py, pz = x, y, z | |
end | |
local function recharge() | |
drone.setLightColor(colorCharing) | |
moveTo(0, 0, 2) | |
if computer.energy() < computer.maxEnergy() * 0.1 then | |
drone.setStatusText("Charging!") | |
while computer.energy() < computer.maxEnergy() * 0.9 do | |
computer.pullSignal(1) | |
end | |
drone.setStatusText(string.format("X:%.1f\nZ:%.1f", cx, cz)) | |
end | |
drone.setLightColor(colorSearching) | |
end | |
local function cargoSize() | |
local result = 0 | |
for slot = 1, drone.inventorySize() do | |
result = result + drone.count(slot) | |
end | |
return result | |
end | |
local function pullItems() | |
-- Only wait up to 5 seconds, avoids dribbling inputs from stalling us. | |
local start = computer.uptime() | |
repeat until not drone.suck(0) or computer.uptime() - start > 5 | |
end | |
local function matchCargo(slot, filter) | |
if not invctrl or not filter or filter == "" then | |
return true | |
end | |
local stack = invctrl.getStackInInternalSlot(slot) | |
return stack and stack.name:match(filter) | |
end | |
local function haveCargoFor(filter) | |
for slot = 1, drone.inventorySize() do | |
if matchCargo(slot, filter) then | |
return true | |
end | |
end | |
end | |
local function dropItems(filter) | |
for slot = 1, drone.inventorySize() do | |
if matchCargo(slot, filter) then | |
drone.select(slot) | |
drone.drop(0) | |
end | |
end | |
end | |
-- List of known waypoints and their positions relative to the position of the | |
-- drone when it was started. Waypoints are detected when the program first | |
-- starts, and when it returns to its home position. | |
local waypoints | |
local function updateWaypoints() | |
waypoints = nav.findWaypoints(range) | |
end | |
local function filterWaypoints(filter) | |
local result = {} | |
for _, w in ipairs(waypoints) do | |
if filter(w) then | |
table.insert(result, w) | |
end | |
end | |
return result | |
end | |
-- Main program loop; keep returning to recharge, then check all inputs | |
-- sequentially, distributing what can be picked up from them to all | |
-- outputs. | |
while true do | |
drone.setStatusText(string.format("X:%.1f\nY:%.1f", px, py)) | |
recharge() | |
updateWaypoints() | |
-- Get waypoints marking input inventories; defined as those with a high | |
-- redstone signal going into them (because there'll usually be more input | |
-- than output inventories). | |
local inputs = filterWaypoints(function(w) return w.redstone > 0 end) | |
local outputs = filterWaypoints(function(w) return w.redstone < 1 end) | |
for _, input in ipairs(inputs) do | |
moveTo(input.position) | |
pullItems() | |
drone.setLightColor(colorDelivering) | |
for _, output in ipairs(outputs) do | |
if cargoSize() == 0 then break end | |
if haveCargoFor(output.label) then | |
moveTo(output.position) | |
dropItems(output.label) | |
end | |
end | |
drone.setLightColor(colorSearching) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment