+-- meant to run on advanced turtle with weak automata
-- setup:
--- equip weak automata
--- place in front of coal/shear chest, facing it
+-- select weak automata and turtle.equipLeft()
+-- place in front of coal/shear/unknown chest, facing it
--- refuel, grab shears (keep two at all times)
--- harvest
--- offload
+-- program flow:
+-- refuel, grab shears (keep two at all times), unload all unknown items
+-- harvest all
+-- offload vines
-- index
-- repeat
+local automata = periperal.wrap("left")
+
local shears =
{ "alloyed:steel_shears"
, "minecraft:shears"
}
--- return positions of shears in inventory
--- might not be useful if countShears and selectShears is implemented
--- local locateShears = function()
--- local t = {}
--- for i = 1, 16 do
--- local item = turtle.getItemDetail(i)
--- if item then
--- for _,name in pairs(shears) do
--- if item.name == name then
--- table.insert(t, i)
--- end
--- end
--- end
--- end
--- end
+-- 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 | nil
+-- 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
- print("looking in", i)
local item = turtle.getItemDetail(i)
- if item then
- for _,name in pairs(t) do
- print("comparing", name, item.name)
- if item.name == name then
- return i
- end
- end
- end
+ 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 nil
+ 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() 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 then
- for _, name in pairs(t) do
- if item.name == name then
- count = count + 1
- break
- end
- end
+ 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 = getItemDetail()
+ if item and oneOf(t, item.name) then
+ return true
+ else
+ local i, e = find(t)
+ if i then return turtle.select(i) 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)
+ local msg = "Could not transfer and select: "
+ if i < 1 or i > 16 then return false, msg .. "Index out of range"
+ 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
--- select shears in inventory if not already selected.
--- returns bool. false means no shears in inventory.
--- local selectShears = function()
--- if not turtle.getItemDetail() then
--- for i = 1, 16 do
--- if item and (item.name == "minecraft:shears" or item.name == "alloyed:steel_shears")
--- (and item
-
+
+-- 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
+ if not select(shears) then return false, "No shears available" end
+ local cut, cut_error = automata.digBlock()
+ 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
--- local shear = function()
--- selectShears()
--- local collect = function()
--- a
+-- for testing purposes
+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 == 87 then -- a, turn left
+ turtle.turnLeft()
+ elseif key == 87 then -- d, turn right
+ turtle.turnRight()
+ elseif key == 32 then -- Space, up
+ turtle.up()
+ elseif key == 340 then -- Shift, down
+ turtle.down()
+ end
+end