--- /dev/null
+-- 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)
--- /dev/null
+-- 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
+++ /dev/null
--- 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
+++ /dev/null
--- 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
--- /dev/null
+-- 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
--- /dev/null
+-- 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
--- /dev/null
+lib/turtle-utils.lua:/lib/turle-utils.lua:o
+vineyard/turtle/harvest.lua:/bin/harvest.lua:o