Adding cobble-loader.lua
authorOlav Bakke Svendsen <mail@olavbs.no>
Fri, 27 Oct 2023 05:27:09 +0000 (07:27 +0200)
committerOlav Bakke Svendsen <mail@olavbs.no>
Fri, 27 Oct 2023 05:27:09 +0000 (07:27 +0200)
cobble-loader.lua [new file with mode: 0644]

diff --git a/cobble-loader.lua b/cobble-loader.lua
new file mode 100644 (file)
index 0000000..89e35a8
--- /dev/null
@@ -0,0 +1,100 @@
+-- cobble-loader.lua
+--
+-- cobble is moved to drawers from limited barrels, trying to keep the drawers
+-- full at all times. redstone signal is emitted from all sides of the computer
+-- when drawers are refilling. input barrels may be upgraded with void.
+
+-- the amount of time (in seconds) between attempted refills when refilling.
+local sleep_time_working = 5
+
+-- the amount of time (in seconds) between attempted refills when full.
+local sleep_time_idle = 5
+
+--------------------------------------------------------------------------------
+
+local outputs = {}
+local inputs = {}
+
+for _,address = in pairs(peripheral.getNames()) do
+  local is_drawer = string.match(address, "standard_drawers")
+  local is_barrel = string.match(address, "limited_barrel")
+  if is_drawer then
+    table.insert(outputs, address)
+  elseif is_barrel then
+    table.insert(inputs, address)
+  end
+end
+
+-- returns ordered list of outputs and how much cobble they have space for.
+-- ordered by free space in decreasing order.
+-- outputs with no empty space are not included in return table.
+-- calculates free space on the assumtion that outputs are drawers without void.
+local output_amounts = function()
+  local t = {}
+  for _,output in ipairs(outputs) do
+    local p = peripheral.wrap(output)
+    local item = p.getItemDetail(2)
+    local count =
+      item and item.name == "minecraft:cobblestone"
+      and item.count or 0
+    local free_space = p.getItemLimit(2) - count
+    if free_space > 0 then 
+      table.insert(t, { address = output, free_space = free_space })
+    end
+  end
+  table.sort(t, function(a, b) return a.free_space > b.free_space end)
+  return t
+end
+
+-- returns ordered list of inputs and how much cobble they have available.
+-- ordered by cobble count in decreasing order.
+-- assumes inputs are limited barrels.
+local input_amounts = function()
+  local t = {}
+  for _,input in ipairs(inputs) do
+    local p = peripheral.wrap(input)
+    local item = p.getItemDetail(1)
+    local count =
+      item and item.name == "minecraft:cobblestone"
+      and item.count
+    table.insert(t, { address = input, count = count })
+  end
+  table.sort(t, function(a, b) return a.count > b.count end)
+  return t
+end
+
+-- moves as much cobble as possible to each output, returning whether or not
+-- there is space for more
+local move_cobble = function()
+  local to_move_total = 0
+  for _,output in ipairs(output_amounts()) do
+    local p = peripheral.wrap(output.address)
+    local to_move = output.free_space
+    to_move_total = to_move_total + output.free_space
+    for _,input in ipairs(input_amounts()) do
+      if to_move <= 0 then break end
+      local moved = p.pullItems(input, 1, math.min(input.count, to_move), 2)
+      -- moved may not be integer if pullItems failed.. look out
+      to_move = to_move - moved
+      to_move_total = to_move_total - moved
+    end
+  end
+  return to_move_total > 0
+end
+
+-- set redstone output on all sides simultaneously
+local generate_cobble = function(bool)
+  for _,side in ipairs({"top","bottom","left","right","front","back"}) do
+    rs.setOutput(side, bool)
+  end
+end
+      
+-- main loop
+while true do
+  while move_cobble() do
+    generate_cobble(true)
+    os.sleep(sleep_time_working)
+  end
+  generate_cobble(false)
+  os.sleep(sleep_time_idle)
+end