Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --pastebin get nLNQiU0W theinsektAPIs/treefarm1
- -- see ziBBd33L for startup program and installation instructions
- --not working, experimental, not tested
- --will plant in middle of room.
- --the outputChest should be in the floor,
- --adjacent to a wall, and intersected by a straight line from the middle of the room.
- --Should be able to handle being restarted at any point in the program
- --except maybe the first time if interrupted while writing to file.
- --position zero is above output chest facing inwards
- --todo: roof, walls and corners at bottom must be walltype
- --
- os.loadAPI("theinsektAPIs/fileHelp")
- os.loadAPI("theinsektAPIs/poz3")
- os.loadAPI("theinsektAPIs/poz3a")
- function treeFarm(wallBlocks,limit)
- --emptyInventory("d", {["minecraft:sapling"]=2,})--debug
- --do return end
- --if this is the first time, or if there was an error before
- --print usage instructions
- local startStuffPath="configs/startStuff"
- local startString=fileHelp.loadString(startStuffPath)
- if startString~="skip" then
- if startString==nil then startString="first" end
- if startString=="first" then
- print("Place this turtle in an enclosed room, with the width in both directions being odd (5 ,7 etc.).")
- print("Put one or more saplings in inventory slot 1, in the turtle.")
- print("Put an output chest in the middle along one of the walls, in the floor.")
- print("Put a fuel chest 2 steps to the left (if looking towards middle from output chest).")
- print("Put a dirt block in middle of the floor.")
- else
- print("Previously quit with error:")
- print(startString)
- end
- print("Press: c continue, e exit,i instructions, r reset configs, u update.")
- --wait for key press
- local _, key =os.pullEvent("key")
- --clear terminal
- --term.clear()
- --term.setCursorPos(1,1)
- if key==keys.c then
- print("continuing...")
- fileHelp.saveString(startStuffPath,"skip")
- elseif key==keys.e then
- print("Exiting...")
- return
- elseif key==keys.i then
- fileHelp.saveString(startStuffPath,"first")
- os.reboot()
- elseif key==keys.r then
- clearConfigs()
- fileHelp.saveString(startStuffPath,"first")
- os.reboot()
- else--
- print("Choice not yet implemented, terminating")
- return
- end
- end--if
- treeFarmStates(wallBlocks,limit)
- end--function
- --wallblocks is a table like this {"minecraft:cobblestone"=true, "minecraft:glass"=true, "minecraft"}
- function treeFarmStates(wallBlocks,limit)
- --state: start
- print("debug, state: start")
- --will save stuff like plantName and dimensions,
- --so that it can be loaded after next restart
- --local tryLoad=true
- --local trySave=true
- --state: getting plantName
- print("debug, state: getting plantName")
- --get type of plant (from file or slot 1)
- local plantName = getItemType(1,"configs/plantName")
- if plantName==nil then
- quitWithError("Error: No plant in slot 1")
- end
- ----(skipped)state: getting fuelName
- --get type of fuel (from file or slot 2)
- --local fuelName = getItemType(2,"configs/fuelName")
- --state: getting room dimensions, get dimensions of room (from file or program)
- print("debug, state: getting room dimensions")
- local dimensions=getDimensions(wallBlocks, limit,"configs/dimensions")
- local halfWidth=math.floor(dimensions["width"]/2)
- --state: defining coordinate points, now it's possible to define some coordinates
- print("debug, state: defining coordinate points")
- --some coords
- --positive x=east
- --positive y=up
- --positive z=south
- --north is if standing on output chest and looking towards plant in the middle
- local outputChestPos={x=0,y=0,z=0,f="n"}--above output chest, looking towards plant in middle of room
- local southWestCorner={x=-halfWidth,y=0,z=0,f="n"}--used as a starting point when harvesting
- local waitPos={x=0,y=0,z=-(halfWidth-1),f="n"}--go north from outputChestPos until before plant
- local fuelPos={x=-2,y=0,z=0,f="n"}--two steps to the left of output chest
- --state: defining keep table
- print("debug, state: defining keep table")
- --what items to keep when emptying the inventory, and how much
- --local keepTable={[plantName]=32,[fuelName]=32}
- local keepTable={[plantName]=32,}
- --state: finding pos
- print("debug, state: finding pos")
- findAndSetPos(dimensions, plantName, wallBlocks,waitPos,outputChestPos)
- while(true) do
- --state: refuelling
- print("debug, state: refueling")
- --refuel if has to little fuel
- gotoAndRefuelFromChestIf(fuelPos, "d",1000,2000)
- --state: waiting
- print("debug, state: waiting")
- --wait until not plant
- while(true) do
- --get what is infront
- local success, data=poz3.inspect("n")
- if not success then
- --plant has somehow disappeared, so goto next state
- break
- end
- if success and data.name~=plantName then
- --it's a tree, or the wrong plant, so goto next state
- break
- end
- --the sappling is still there so wait for a while
- os.sleep(10)
- end
- --state: destroying plant position
- print("debug, state: destroying plant position")
- --dig if it's not a wall
- if not isBlockMatch("n", wallBlocks) then
- poz3.dig("n")
- end
- --state: harvesting/clearing (destroy not plant and not wall, then dcube2 inside room)
- print("debug, state: harvesting/clearing")
- harvest(dimensions, southWestCorner)
- --state: emptying inventory
- print("debug, state: emptying inventory")
- if not poz3a.digToCoords2(outputChestPos) then
- quitWithError("Error: failed when trying to go to output chest.")
- end
- emptyInventory("d", keepTable)
- --state: planting
- print("debug, state: planting")
- --goto plant/wait position
- if not poz3a.digToCoords2(waitPos) then
- quitWithError("Error: failed when trying to go to wait position (infront of plant).")
- end
- --place/plant sapling
- if not placeItem("n",plantName) then
- quitWithError("Error: failed when trying to place sapling.")
- end
- end
- end--main
- function gotoAndRefuelFromChestIf(fuelPos, direction,lower,upper)
- --check if fuel level is below lower limit
- local fuelLevel=turtle.getFuelLevel()
- --quit if doesnโt need to refuel (fuel level isn't below lower)
- local fuelLevel=turtle.getFuelLevel()
- if fuelLevel == "unlimited" or fuelLevel >= lower then
- return
- end
- --goto refuelling chest
- if not poz3a.digToCoords2(fuelPos) then
- quitWithError("Error: failed when trying to go to refuelling position.")
- end
- --refuel from chest
- if not refuelFromChest(direction, upper) then
- quitWithError("Error: failed when refuelling from chest.")
- end
- end
- --suck fuel from a chest in the given direction
- --and refuel until fuel level reaches upper (upper bound)
- function refuelFromChest(direction,upper)
- --return true if has unlimited fuel
- if turtle.getFuelLevel() == "unlimited" then return true end
- --check upper
- if upper>turtle.getFuelLimit() then upper=turtle.getFuelLimit() end
- --select the slot to place the fuel in
- local slot=findEmptyInventorySlot()
- if slot==-1 then
- return false
- end
- turtle.select(slot)
- --refuel from chest
- while(turtle.getFuelLevel()<upper) do
- if not poz3.suck(direction,1) then
- --could not suck fuel from fuel chest
- return false
- end
- if not turtle.refuel() then
- --could not refuel from the selected slot
- --maybe it's not a fuel
- return false
- end
- end
- --refuelled!
- return true
- end
- function findEmptyInventorySlot()
- for slot=1,16 do
- if turtle.getItemCount(slot)==0 then
- return slot
- end
- end
- return -1
- end
- function placeItem(direction, itemName)
- local slot=getItemSlot(itemName)
- if slot==-1 then return false end
- turtle.select(slot)
- return poz3.place(direction)
- end
- function getItemSlot(itemName)
- for slot=1, 16 do
- local data=turtle.getItemDetail(slot)
- if data and data.name==itemName then
- return slot
- end
- end
- return -1
- end
- --not tested
- --example keepTable: {"minecraft:sappling"=32,"minecraft:charcoal"=32}
- function emptyInventory(direction, keepTable)
- local amounts={}
- for slot=1, 16 do
- local data=turtle.getItemDetail(slot)
- if data then
- if keepTable[data.name] then
- if not amounts[data.name] then amounts[data.name]=0 end
- local limit=keepTable[data.name]
- amount = turtle.getItemCount(slot) + amounts[data.name]
- if amount>limit then
- local dropAmount=amount-limit
- turtle.select(slot)
- poz3.drop(direction,dropAmount)
- amount=limit
- end --if amount>limit
- amounts[data.name]=amount
- else --if keep
- --drop whole stack
- turtle.select(slot)
- poz3.drop(direction)
- end
- end--if data
- end --for
- return true
- end
- function harvest(dimensions, southWestCorner)
- --go to southwest corner
- if not poz3a.digToCoords2(southWestCorner) then
- quitWithError("Error: failed when trying to go to southWestCorner.")
- end
- --harvest, digcube ,refuel=false, return to origin=true
- if not poz3a.callDigCube("u",dimensions["height"],"e",dimensions["width"],"n",dimensions["width"],false,true) then
- quitWithError("Error: failed when digging everything inside the room.")
- end
- --returned to south west corner
- end
- --does not need a known postion
- function getDimensions(wallBlocks,limit, path)
- local dimensions=nil
- if path then
- dimensions = fileHelp.loadValue(path)
- if dimensions~=nil then return dimensions end
- end
- --measure dimensions
- --go to a top corner
- local len1,data=digGoUntilWall("u",wallBlocks,limit)
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- local len2,data=digGoUntilWall("w",wallBlocks,limit)
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- local len3,data=digGoUntilWall("s",wallBlocks,limit)
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- --measure height
- local height,data=digGoUntilWall("d",wallBlocks,limit)
- height=height+1--because needs to count place where turtle stood
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- if height<2 then error("Room error: the room must have a height that is 2 or larger.") end
- --measure width1
- local width1,data=digGoUntilWall("e",wallBlocks,limit)
- width1=width1+1--because needs to count place where turtle stood
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- if width1<5 then
- quitWithError("Room error: the width of the room must be 5 or larger.")
- end
- if (width1 % 2) == 0 then
- if not data then
- quitWithError("Room error: the width of the room must be odd number, examples 5 ,7, 9 etc.")
- end
- end
- --measure width2
- local width2,data=digGoUntilWall("n",wallBlocks,limit)
- width2=width2+1--because needs to count place where turtle stood
- if turtle.getFuelLevel() == 0 then quitWithError("Turtle error: turtle is out of fuel.") end
- if not data then quitWithError("Room error: reached limit without finding a wall block.") end
- if width1 ~= width2 then quitWithError("Room error: width1 and width2 must be the same in the room.") end
- --save and return dimensions
- dimensions={["width"]=width1, ["height"]=height,}
- if path then
- fileHelp.saveValue(path,dimensions)
- end
- return dimensions
- end
- --returns true if should be waiting
- --returns false if should be harvesting
- function findAndSetPos(dimensions, plantName, wallBlocks,waitPos,outputChestPos)
- local success,data=poz3.inspect("f")
- if success then
- if data.name==plantName then
- --known pos, at waitpos
- print("debug, pos: waitPos")
- poz3.setPos2(waitPos)
- return
- end --if
- --if it's not a wall it might be
- --a sapling of wrong type so destroy it
- if not wallBlocks[data.name] then
- print("removing potential bad plant")
- poz3.dig("f")
- end
- end --if
- --unknown pos, so find it
- local halfWidth=math.floor(dimensions["width"]/2)
- findOutputChest(dimensions,halfWidth,wallBlocks)
- print("debug, pos: outputChestPos")
- poz3.setPos2(outputChestPos)
- end --function
- --Goes to the outputChestPos without knowing the current position
- function findOutputChest(dimensions,halfWidth,wallBlocks)
- --go to a top corner
- local _,data=digGoUntilWall("u",wallBlocks,dimensions["height"])
- if data==nil then quitWithError("Room error: a wall is missing, or dimensions have changed") end
- local _,data=digGoUntilWall("w",wallBlocks,dimensions["width"])
- if data==nil then quitWithError("Room error: a wall is missing, or dimensions have changed") end
- local _,data=digGoUntilWall("s",wallBlocks,dimensions["width"])
- if data==nil then quitWithError("Room error: a wall is missing, or dimensions have changed") end
- --go to bottom corner
- local len1,data=digGoUntilWall("d",wallBlocks,dimensions["height"]+1)
- if data==nil then quitWithError("Room error: a wall is missing, or dimensions have changed") end
- if len1+1 ~= dimensions["height"] then quitWithError("Room error: a wall is missing, or dimensions have changed") end
- --go in circle looking for chest,
- local turnDirectionIfFound="l"
- if checkForMiddleChest("e",halfWidth,wallBlocks,turnDirectionIfFound) then return true end
- if checkForMiddleChest("n",halfWidth,wallBlocks,turnDirectionIfFound) then return true end
- if checkForMiddleChest("w",halfWidth,wallBlocks,turnDirectionIfFound) then return true end
- if checkForMiddleChest("s",halfWidth,wallBlocks,turnDirectionIfFound) then return true end
- quitWithError("Room error: there is no output chest at the four possible positions, or room dimensions have changed")
- end
- --must be going along right wall
- function checkForMiddleChest(direction,halfWidth,wallBlocks,directionIfFound)
- local _,data=digGoUntilWall(direction,wallBlocks,halfWidth)
- if data then quitWithError("Room error: a wall block is inside room, or dimensions have changed") end
- local success, data=poz3.inspect("d")
- if success and data and data.name=="minecraft:chest" then
- poz3.turn(directionIfFound)
- return true
- end
- local _,data=digGoUntilWall(direction,wallBlocks,halfWidth+1)
- if not data then quitWithError("Room error: a wall block is missing, or dimensions have changed") end
- return false
- end
- --returns blocksTraveled, blockData if encountered a wall
- --returns limit, nil if travelled limit blocks
- --returns blokcsTraveled, nil if blocked by something undigable (impossible?)
- function digGoUntilWall(direction, wallBlocks,limit)
- for i=1, limit do
- local went, data = digGoIfNotWall(direction, wallBlocks)
- if not went then return i-1, data end
- end
- return limit,nil
- end
- --digs or goes one step in the given direction
- --returns true,nil if went
- --returns false, nil if could not dig through non wall block
- --returns false, blockData if reached wall
- --will continue trying if blocked by player
- function digGoIfNotWall(direction,wallBlocks)
- --no fuel
- if turtle.getFuelLevel() == 0 then return false,nil end
- while(true) do
- --check block in direction
- local success, data=poz3.inspect(direction)
- if success then
- if wallBlocks[data.name] then
- return false, data
- end
- if not poz3.dig(direction) then return false, nil end
- end
- --go in direction
- if poz3.go(direction) then return true, nil end
- end
- end
- --resulting direction could be changed
- --returns the name of the block, if it's one of the blocks
- --blocks could be a string, or a table with string keys
- function isBlockMatch(direction, blocks)
- local success, data=poz3.inspect(direction)
- if success then
- if type(blocks)=="string" then
- if data.name=blocks
- return data.name
- end--if
- return nil
- end--if type
- if blocks[data.name]
- return data.name
- end--if
- end--if success
- return nil
- end--function
- --first tries to get itemname from the given file path
- --second tries to find name of the item in the given slotNum
- --if got itemName from slot and doSave is true, then saves the itemName in the given path
- function getItemType(slotNum,path)
- local itemName=nil
- if path then
- itemName=fileHelp.loadString(path)
- end
- if itemName==nil then
- local data=turtle.getItemDetail(slotNum)
- if data then
- itemName=data.name
- if path then
- fileHelp.saveString(path,itemName)
- end
- end
- end
- return itemName
- end
- function quitWithError(errorMessage)
- fileHelp.saveString("configs/startStuff",errorMessage)
- error(errorMessage,2)
- end
- function clearConfigs()
- --delete the configs folder
- fs.delete("configs")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement