added install.lua, renamed and moved stuff
authorOlav Bakke Svendsen <mail@olavbs.no>
Wed, 15 May 2024 16:51:48 +0000 (18:51 +0200)
committerOlav Bakke Svendsen <mail@olavbs.no>
Wed, 15 May 2024 16:51:48 +0000 (18:51 +0200)
common/install.lua [new file with mode: 0644]
lib/turtle-utils.lua [new file with mode: 0644]
vines/gantry-harvester.lua [deleted file]
vines/turtle.lua [deleted file]
vineyard/gantry-harvester.lua [new file with mode: 0644]
vineyard/turtle/harvest.lua [new file with mode: 0644]
vineyard/turtle/package [new file with mode: 0644]

diff --git a/common/install.lua b/common/install.lua
new file mode 100644 (file)
index 0000000..0fe416c
--- /dev/null
@@ -0,0 +1,11 @@
+-- install.lua
+-- looks for package-file in git repo and runs dl.lua on every line
+-- usage:
+-- install repo:[tag] remote/path
+
+local tmp = textutils.serialize(math.random(100000,999999))
+shell.run("dl "..args[1].." "..args[2].."/package:"..tmp)
+for line in lines(tmp) do
+  shell.run("dl "..line)
+end
+fs.delete(tmp)
diff --git a/lib/turtle-utils.lua b/lib/turtle-utils.lua
new file mode 100644 (file)
index 0000000..081acb1
--- /dev/null
@@ -0,0 +1,148 @@
+-- turtle-utils.lua
+--
+-- depends on:
+--   oneOf
+--
+-- implements:
+-- findItem : list of item names -> index | false message
+-- findEmpty : index | false message
+-- count : list of item names -> count
+-- selectItem : list of item names -> true | false message
+-- transferAndSelect : index -> list of items -> true | false message
+-- commandMap : t f
+-- runStringCommand : string -> true | false message
+-- rep : number of repeats -> string -> string | nil
+
+---------------------------------------   for now
+-- t a -> a -> bool
+-- returns whether a is found in t
+local oneOf = function(t, a)
+  for _,b in pairs(t) do
+    if b == a then return true end
+  end
+  return false
+end
+--------------------------------------
+
+-- findItem : list of item names -> index | false message
+-- returns the first inventory index containing an item from list t
+-- if no item is found, returns nil
+local findItem = function(t)
+  for i = 1, 16 do
+    local item = turtle.getItemDetail(i)
+    if item and oneOf(t, item.name) then return i end
+  end
+  return false, "Item(s) not found"
+end
+
+-- findEmpty : index | false message
+-- returns the first empty slot
+-- if no empty slot is found, returns nil
+local findEmpty = function()
+  for i = 1, 16 do if not turtle.getItemDetail(i) then return i end end
+  return false, "No empty slot"
+end
+
+-- count : list of item names -> count
+-- counts how many slots contain an item from list t
+-- (does not count individual items)
+local count = function(t)
+  local c = 0
+  for i = 1, 16 do
+    local item = turtle.getItemDetail(i)
+    if item and oneOf(t, item.name) then
+      c = c + 1
+      break
+    end
+  end
+end
+
+-- selectItem : list of item names -> true | false message
+-- select first slot containing an item from list t if not already selected.
+-- returns bool.
+local selectItem = function(t)
+  local item = turtle.getItemDetail()
+  if item and oneOf(t, item.name) then
+    return true
+  else
+    local i, e = find(t)
+    if i then 
+      turtle.select(i)
+      return true
+    end
+  end
+  return false, "Nothing to select: " .. e
+end
+
+-- transferAndSelect : index -> list of items -> true | false message
+-- like selectItem, selects item from list, but tries to move it to the first slot.
+-- requires an empty slot to move items around.
+-- (this function exists because weak automata cannot digBlock with tools in slots >9)
+local transferAndSelect = function(i, t)
+  if i < 1 or i > 16 then return false, msg .. "Index out of range" end
+  -- if a wanted item already is in the wanted slot, select it and return early
+  local item = turtle.getItemDetail(i)
+  if item and oneOf(t, item.name) then
+    turtle.select(i)
+    return true
+  end
+  local msg = "Could not transfer and select: "
+  local i_tmp, e = findEmpty()
+  if not i_tmp then return false, msg .. e end
+  local i_from, e = find(t)
+  if not i_from then return false, msg .. e end
+  -- if the i'th slot is free, skip the unnecessary item shuffle
+  if not turtle.getItemDetail(i) then
+    turtle.select(i_from)
+    turtle.transferTo(i)
+  else
+    turtle.select(i)
+    turtle.transferTo(i_tmp)
+    turtle.select(i_from)
+    turtle.transferTo(i)
+--     turtle.select(i_tmp)
+--     turtle.transferTo(i_from)
+  end
+  turtle.select(i)
+  return true
+end
+
+
+-- commands as strings
+-- chars corresponds to actions, when immediatel followed by a number, repeats the action that many times
+-- "udfblrh" = up -> down -> forward -> backward -> turn left -> turn right -> harvest
+-- "u15r"  = 15x up -> turn right
+-- "u15 r" = 15x up -> turn right
+-- "u1 5r" = invalid
+
+-- commandMap : t f
+local commandMap =
+  { ["u"] = turtle.up
+  , ["d"] = turtle.down
+  , ["f"] = turtle.forward
+  , ["b"] = turtle.back
+  , ["l"] = turtle.turnLeft
+  , ["r"] = turtle.turnRight
+  }
+
+-- runStringCommand : string -> true | false message
+local runCommandString = function(str, map)
+  local c, n, rest = string.match(string.gsub(str, "^%s+", ""), "^(%w)(%d*)(.*)")
+  if not c then return true end
+  if n == "" then n = 1 else n = tonumber(n) end
+  for i = 1, n do map[c]() end
+--     print(cmd, tostring(i).."/"..tostring(n))
+--   end
+  return turtle.runCommandString(rest)
+end 
+
+-- rep : number of repeats -> string -> string | nil
+-- repeats string n times
+local rep = function(n, str)
+  if not n or n < 0 then return nil end
+  local s = ""
+  for i = 1, n do
+    s = s .. str
+  end
+  return s
+end
diff --git a/vines/gantry-harvester.lua b/vines/gantry-harvester.lua
deleted file mode 100644 (file)
index 6529a25..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
--- xy gantry with deployer and shears
-
--- timings
--- works with 64 RPM
-local vertical_tick   = 0.5
-local horizontal_time = 4.5
-local stanby_time     = 60*30
-local rows            = 10
-
--- redstone IO
-local enable      = "front" -- input:  true -> enable
-local y_gearshift = "left"  -- output: true -> move home
-local y_clutch    = "top"   -- output: true -> disengage
-
-local reset = function()
-  for _, out in pairs({y_gearshift, y_clutch}) do
-    rs.setOutput(out, false)
-  end
-end
-
-local up = function()
-  rs.setOutput(y_gearshift, true)
-  rs.setOutput(y_clutch, false)
-  os.sleep(vertical_tick)
-  rs.setOutput(y_cluctch, true)
-end
-
-local harvest = function()
-  for i = 1, rows-1 do
-    up()
-    os.sleep(horizontal_time)
-  end
-  reset()
-end
-
-while true do
-  if rs.getInput(enable) then
-    harvest()
-    os.sleep(standby_time)
-  else
-    os.pullEvent("redstone")
-  end
-end
diff --git a/vines/turtle.lua b/vines/turtle.lua
deleted file mode 100644 (file)
index 66af0cc..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
--- meant to run on advanced turtle with weak automata
--- setup:
--- select weak automata and turtle.equipLeft()
--- place in front of coal/shear/unknown chest, facing it
-
--- program flow:
--- refuel, grab shears (keep two at all times), unload all unknown items
--- harvest all
--- offload vines
--- index
--- repeat
-
-local automata = peripheral.wrap("left")
-
-local shears =
-  { "alloyed:steel_shears"
-  , "minecraft:shears"
-  }
-
--- t a -> a -> bool
--- returns whether a is found in t
-local oneOf = function(t, a)
-  for _,b in pairs(t) do
-    if b == a then return true end
-  end
-  return false
-end
-
--- find : list of item names -> index | false message
--- returns the first inventory index containing an item from list t
--- if no item is found, returns nil
-local find = function(t)
-  for i = 1, 16 do
-    local item = turtle.getItemDetail(i)
-    if item and oneOf(t, item.name) then return i end
---       for _,name in pairs(t) do
---         if item.name == name then
---           return i
---         end
---       end
---     end
-  end
-  return false, "Item(s) not found"
-end
-
--- findEmpty : index | false message
--- returns the first empty slot
--- if no empty slot is found, returns nil
-local findEmpty = function()
-  for i = 1, 16 do if not turtle.getItemDetail(i) then return i end end
-  return false, "No empty slot"
-end
-
--- count : list of item names -> count
--- counts how many slots contain an item from list t
--- (does not count individual items)
-local count = function(t)
-  local c = 0
-  for i = 1, 16 do
-    local item = turtle.getItemDetail(i)
-    if item and oneOf(t, item.name) then
-      c = c + 1
-      break
-    end
---       for _, name in pairs(t) do
---         if item.name == name then
---           c = c + 1
---           break
---         end
---       end
---     end
-  end
-end
-
--- select : list of item names -> true | false message
--- select first slot containing an item from list t if not already selected.
--- returns bool.
-local select = function(t)
-  local item = turtle.getItemDetail()
-  if item and oneOf(t, item.name) then
-    return true
-  else
-    local i, e = find(t)
-    if i then 
-      turtle.select(i)
-      return true
-    end
-  end
-  return false, "Nothing to select: " .. e
-end
-
--- transferAndSelect : index -> list of items -> true | false message
--- like select, selects item from list, but tries to move it to the first slot.
--- requires an empty slot to move items around.
--- (this function exists because weak automata cannot digBlock with tools in slots >9)
-local transferAndSelect = function(i, t)
-  if i < 1 or i > 16 then return false, msg .. "Index out of range" end
-  -- if a wanted item already is in the wanted slot, select it and return early
-  local item = turtle.getItemDetail(i)
-  if item and oneOf(t, item.name) then
-    turtle.select(i)
-    return true
-  end
-  local msg = "Could not transfer and select: "
-  local i_tmp, e = findEmpty()
-  if not i_tmp then return false, msg .. e end
-  local i_from, e = find(t)
-  if not i_from then return false, msg .. e end
-  -- if the i'th slot is free, skip the unnecessary item shuffle
-  if not turtle.getItemDetail(i) then
-    turtle.select(i_from)
-    turtle.transferTo(i)
-  else
-    turtle.select(i)
-    turtle.transferTo(i_tmp)
-    turtle.select(i_from)
-    turtle.transferTo(i)
---     turtle.select(i_tmp)
---     turtle.transferTo(i_from)
-  end
-  turtle.select(i)
-  return true
-end
-
-
--- harvest : true | false message
--- check for vine, select shears, use, suck
-local harvest = function()
-  local facing_block, block = turtle.inspect()
-  if not (facing_block and block.name == "minecraft:vine") then return false, "Not facing vine" end
-  local selected, select_error = transferAndSelect(1, shears)
-  if not selected then return false, "No shears available: " .. select_error end
-  local cut, cut_error = automata.digBlock()
-  while cut_error == "dig is on cooldown" do
-    sleep(0.1)
-    cut, cut_error = automata.digBlock()
-  end
-  if not cut then return false, "Could not cut vine: " .. cut_error end
-  local collect, collect_error = automata.collectItems()
-  if not collect then return false, "Could not collect vine: " .. collect_error end
-  return true
-end
-
-
--- commands as strings
--- chars corresponds to actions, when immediatel followed by a number, repeats the action that many times
--- "udfblrh" = up -> down -> forward -> backward -> turn left -> turn right -> harvest
--- "u15r"  = 15x up -> turn right
--- "u15 r" = 15x up -> turn right
--- "u1 5r" = invalid
-
--- commands : t f
-local commands =
-  { ["u"] = turtle.up
-  , ["d"] = turtle.down
-  , ["f"] = turtle.forward
-  , ["b"] = turtle.back
-  , ["l"] = turtle.turnLeft
-  , ["r"] = turtle.turnRight
-  , ["h"] = harvest
-  }
-
--- runCommand : string -> true | false message
-local runCommand
-runCommand = function(str)
-  local c, n, rest = string.match(string.gsub(str, "^%s+", ""), "^(%w)(%d*)(.*)")
-  if not c then return true end
-  if n == "" then n = 1 else n = tonumber(n) end
-  for i = 1, n do commands[c]() end
---     print(cmd, tostring(i).."/"..tostring(n))
---   end
-  return runCommand(rest)
-end 
-
--- rep : number of repeats -> string -> string | nil
--- repeats string n times
-local rep = function(n, str)
-  if not n or n < 0 then return nil end
-  local s = ""
-  for i = 1, n do
-    s = s .. str
-  end
-  return s
-end
-    
--- for testing purposes
-local sequence = function()
-  print("pretending to unload stray items")
-  print("pretending to refuel")
-  print("pretending to stock up on shears")
-  local enter_vineyard = "rf3hfhflfr2d2"
-  local harvest_up = function(n) return rep(n, "hu2") .. "h" end
-  local harvest_down = function(n) return rep(n, "hd2") .. "h" end
-  local harvest_ns = rep(2, harvest_up(8).."lfdr"..harvest_down(7).."lfdr")..harvest_up(8)
-  local harvest_ew = rep(2, harvest_down(8).."lfur"..harvest_up(7).."lfur")..harvest_down(8)
-  local go_to_dropoff = "u2lhfrhf5lf2"
-  print("running harvesting sequence...")
-  local seq =
-       enter_vineyard
-    .. harvest_ns .. "l" .. harvest_ew .. "l"
-    .. harvest_ns .. "l" .. harvest_ew
-    .. go_to_dropoff
-  return runCommand(seq)
-end
-
-while true do
-  local _, key = os.pullEvent("key")
-  if key == 72 then -- h
-    print("harvest")
-    print(harvest())
---     local harvested, e = harvest() 
---     if harvested then print("Harvested vine") else print("Could not harvest vine: " .. e) end
-
-  elseif key == 49 then -- 1, select shears
-    print("select shears")
-    print(select(shears))
-  elseif key == 50 then -- 2, transfer and select shears
-    print("transfer and select shears")
-    print(transferAndSelect(1, shears))
-  elseif key == 87 then -- w, forward
-    turtle.forward()
-  elseif key == 83 then -- s, back
-    turtle.back()
-  elseif key == 65 then -- a, turn left
-    turtle.turnLeft()
-  elseif key == 68 then -- d, turn right
-    turtle.turnRight()
-  elseif key == 32 then -- Space, up
-    turtle.up()
-  elseif key == 340 then -- Shift, down
-    turtle.down()
-  elseif key == 257 then -- Enter, run sequence
-    print("Is the turtle indexed properly?\n(press y to confirm)")
-    local _, char = os.pullEvent("char")
-    if char == "y" then sequence() else print("Aborted") end
-  end
-end
diff --git a/vineyard/gantry-harvester.lua b/vineyard/gantry-harvester.lua
new file mode 100644 (file)
index 0000000..6529a25
--- /dev/null
@@ -0,0 +1,43 @@
+-- xy gantry with deployer and shears
+
+-- timings
+-- works with 64 RPM
+local vertical_tick   = 0.5
+local horizontal_time = 4.5
+local stanby_time     = 60*30
+local rows            = 10
+
+-- redstone IO
+local enable      = "front" -- input:  true -> enable
+local y_gearshift = "left"  -- output: true -> move home
+local y_clutch    = "top"   -- output: true -> disengage
+
+local reset = function()
+  for _, out in pairs({y_gearshift, y_clutch}) do
+    rs.setOutput(out, false)
+  end
+end
+
+local up = function()
+  rs.setOutput(y_gearshift, true)
+  rs.setOutput(y_clutch, false)
+  os.sleep(vertical_tick)
+  rs.setOutput(y_cluctch, true)
+end
+
+local harvest = function()
+  for i = 1, rows-1 do
+    up()
+    os.sleep(horizontal_time)
+  end
+  reset()
+end
+
+while true do
+  if rs.getInput(enable) then
+    harvest()
+    os.sleep(standby_time)
+  else
+    os.pullEvent("redstone")
+  end
+end
diff --git a/vineyard/turtle/harvest.lua b/vineyard/turtle/harvest.lua
new file mode 100644 (file)
index 0000000..c57a9c0
--- /dev/null
@@ -0,0 +1,92 @@
+-- meant to run on advanced turtle with weak automata
+-- setup:
+-- select weak automata and turtle.equipLeft()
+-- place in front of coal/shear/unknown chest, facing it
+
+-- program flow:
+-- refuel, grab shears (keep two at all times), unload all unknown items
+-- harvest all
+-- offload vines
+-- index
+-- repeat
+
+local tu = require("lib/turtle-utils.lua")
+local automata = peripheral.wrap("left")
+
+local shears =
+  { "alloyed:steel_shears"
+  , "minecraft:shears"
+  }
+
+-- harvest : true | false message
+-- check for vine, select shears, use, suck
+local harvest = function()
+  local facing_block, block = turtle.inspect()
+  if not (facing_block and block.name == "minecraft:vine") then return false, "Not facing vine" end
+  local selected, select_error = tu.transferAndSelect(1, shears)
+  if not selected then return false, "No shears available: " .. select_error end
+  local cut, cut_error = automata.digBlock()
+  while cut_error == "dig is on cooldown" do
+    sleep(0.1)
+    cut, cut_error = automata.digBlock()
+  end
+  if not cut then return false, "Could not cut vine: " .. cut_error end
+  local collect, collect_error = automata.collectItems()
+  if not collect then return false, "Could not collect vine: " .. collect_error end
+  return true
+end
+
+-- for testing purposes
+local sequence = function()
+  local map = tu.movementMap
+  map["h"] = harvest
+  print("pretending to unload stray items")
+  print("pretending to refuel")
+  print("pretending to stock up on shears")
+  local enter_vineyard = "rf3hfhflfr2d2"
+  local harvest_up = function(n) return tu.rep(n, "hu2") .. "h" end
+  local harvest_down = function(n) return tu.rep(n, "hd2") .. "h" end
+  local harvest_ns = tu.rep(2, harvest_up(8).."lfdr"..harvest_down(7).."lfdr")..harvest_up(8)
+  local harvest_ew = tu.rep(2, harvest_down(8).."lfur"..harvest_up(7).."lfur")..harvest_down(8)
+  local go_to_dropoff = "u2lhfrhf5lf2"
+  print("running harvesting sequence...")
+  local seq =
+       enter_vineyard
+    .. harvest_ns .. "l" .. harvest_ew .. "l"
+    .. harvest_ns .. "l" .. harvest_ew
+    .. go_to_dropoff
+  return runStringCommand(seq, map)
+end
+
+while true do
+  local _, key = os.pullEvent("key")
+  if key == 72 then -- h
+    print("harvest")
+    print(harvest())
+--     local harvested, e = harvest() 
+--     if harvested then print("Harvested vine") else print("Could not harvest vine: " .. e) end
+
+  elseif key == 49 then -- 1, select shears
+    print("select shears")
+    print(select(shears))
+  elseif key == 50 then -- 2, transfer and select shears
+    print("transfer and select shears")
+    print(tu.transferAndSelect(1, shears))
+  elseif key == 87 then -- w, forward
+    turtle.forward()
+  elseif key == 83 then -- s, back
+    turtle.back()
+  elseif key == 65 then -- a, turn left
+    turtle.turnLeft()
+  elseif key == 68 then -- d, turn right
+    turtle.turnRight()
+  elseif key == 32 then -- Space, up
+    turtle.up()
+  elseif key == 340 then -- Shift, down
+    turtle.down()
+  elseif key == 257 then -- Enter, run sequence
+    print("Is the turtle indexed properly?\n(press y to confirm)")
+    local _, char = os.pullEvent("char")
+    if char == "y" then sequence() else print("Aborted") end
+  end
+end
diff --git a/vineyard/turtle/package b/vineyard/turtle/package
new file mode 100644 (file)
index 0000000..b62febb
--- /dev/null
@@ -0,0 +1,2 @@
+lib/turtle-utils.lua:/lib/turle-utils.lua:o
+vineyard/turtle/harvest.lua:/bin/harvest.lua:o