spaces->tab, equipper improvements, supertreefarm rewrite, follow improvements, sensor cleanup, milo multiple items allowed in recipes, remote canvas access

This commit is contained in:
kepler155c@gmail.com
2019-06-18 15:23:20 -04:00
parent 3b9b509429
commit 045b32884f
162 changed files with 20448 additions and 20286 deletions

View File

@@ -6,60 +6,60 @@ local turtle = _G.turtle
local CRAFTING_TABLE = 'minecraft:crafting_table'
local function clearGrid(inventory)
for i = 1, 16 do
local count = turtle.getItemCount(i)
if count > 0 then
inventory:insert(i, count)
if turtle.getItemCount(i) ~= 0 then
return false
end
end
end
return true
for i = 1, 16 do
local count = turtle.getItemCount(i)
if count > 0 then
inventory:insert(i, count)
if turtle.getItemCount(i) ~= 0 then
return false
end
end
end
return true
end
function turtle.craftItem(item, count, inventoryInfo)
local success, msg
local success, msg
local inventory = Adapter.wrap(inventoryInfo)
if not inventory then
return false, 'Invalid inventory'
end
local inventory = Adapter.wrap(inventoryInfo)
if not inventory then
return false, 'Invalid inventory'
end
local equipped, side
if not turtle.isEquipped('workbench') then
local modemSide = turtle.isEquipped('modem') or 'right'
local osides = { left = 'right', right = 'left' }
side = osides[modemSide]
if not turtle.select(CRAFTING_TABLE) then
clearGrid(inventory)
if not turtle.selectOpenSlot() then
return false, 'Inventory is full'
end
if not inventory:provide({ name = CRAFTING_TABLE, damage = 0 }, 1) then
return false, 'Missing crafting table'
end
end
local equipped, side
if not turtle.isEquipped('workbench') then
local modemSide = turtle.isEquipped('modem') or 'right'
local osides = { left = 'right', right = 'left' }
side = osides[modemSide]
if not turtle.select(CRAFTING_TABLE) then
clearGrid(inventory)
if not turtle.selectOpenSlot() then
return false, 'Inventory is full'
end
if not inventory:provide({ name = CRAFTING_TABLE, damage = 0 }, 1) then
return false, 'Missing crafting table'
end
end
local slot = turtle.select(CRAFTING_TABLE)
turtle.equip(side, CRAFTING_TABLE)
equipped = turtle.getItemDetail(slot.index)
end
local slot = turtle.select(CRAFTING_TABLE)
turtle.equip(side, CRAFTING_TABLE)
equipped = turtle.getItemDetail(slot.index)
end
clearGrid(inventory)
success, msg = Craft.craftRecipe(item, count or 1, inventory)
clearGrid(inventory)
success, msg = Craft.craftRecipe(item, count or 1, inventory)
if equipped then
turtle.selectOpenSlot()
inventory:provide({ name = equipped.name, damage = equipped.damage }, 1)
turtle.equip(side, equipped.name .. ':' .. equipped.damage)
end
if equipped then
turtle.selectOpenSlot()
inventory:provide({ name = equipped.name, damage = equipped.damage }, 1)
turtle.equip(side, equipped.name .. ':' .. equipped.damage)
end
return success, msg
return success, msg
end
function turtle.canCraft(item, count, items)
return Craft.canCraft(item, count, items)
return Craft.canCraft(item, count, items)
end
return true

View File

@@ -9,167 +9,167 @@ local box = { }
local oldCallback
local function toKey(pt)
return table.concat({ pt.x, pt.y, pt.z }, ':')
return table.concat({ pt.x, pt.y, pt.z }, ':')
end
local function addNode(node)
for i = 0, 5 do
local hi = turtle.getHeadingInfo(i)
local testNode = { x = node.x + hi.xd, y = node.y + hi.yd, z = node.z + hi.zd }
for i = 0, 5 do
local hi = turtle.getHeadingInfo(i)
local testNode = { x = node.x + hi.xd, y = node.y + hi.yd, z = node.z + hi.zd }
if Point.inBox(testNode, box) then
local key = toKey(testNode)
if not checkedNodes[key] then
nodes[key] = testNode
end
end
end
if Point.inBox(testNode, box) then
local key = toKey(testNode)
if not checkedNodes[key] then
nodes[key] = testNode
end
end
end
end
local function dig(action)
local directions = {
top = 'up',
bottom = 'down',
}
local directions = {
top = 'up',
bottom = 'down',
}
-- convert to up, down, north, south, east, west
local direction = directions[action.side] or
turtle.getHeadingInfo(turtle.point.heading).direction
-- convert to up, down, north, south, east, west
local direction = directions[action.side] or
turtle.getHeadingInfo(turtle.point.heading).direction
local hi = turtle.getHeadingInfo(direction)
local node = { x = turtle.point.x + hi.xd, y = turtle.point.y + hi.yd, z = turtle.point.z + hi.zd }
local hi = turtle.getHeadingInfo(direction)
local node = { x = turtle.point.x + hi.xd, y = turtle.point.y + hi.yd, z = turtle.point.z + hi.zd }
if Point.inBox(node, box) then
if Point.inBox(node, box) then
local key = toKey(node)
checkedNodes[key] = true
nodes[key] = nil
local key = toKey(node)
checkedNodes[key] = true
nodes[key] = nil
if action.dig() then
addNode(node)
repeat until not action.dig() -- sand, etc
return true
end
end
if action.dig() then
addNode(node)
repeat until not action.dig() -- sand, etc
return true
end
end
end
local function move(action)
if action == 'turn' then
dig(turtle.getAction('forward'))
elseif action == 'up' then
dig(turtle.getAction('up'))
dig(turtle.getAction('forward'))
elseif action == 'down' then
dig(turtle.getAction('down'))
dig(turtle.getAction('forward'))
elseif action == 'back' then
dig(turtle.getAction('up'))
dig(turtle.getAction('down'))
end
if action == 'turn' then
dig(turtle.getAction('forward'))
elseif action == 'up' then
dig(turtle.getAction('up'))
dig(turtle.getAction('forward'))
elseif action == 'down' then
dig(turtle.getAction('down'))
dig(turtle.getAction('forward'))
elseif action == 'back' then
dig(turtle.getAction('up'))
dig(turtle.getAction('down'))
end
if oldCallback then
oldCallback(action)
end
if oldCallback then
oldCallback(action)
end
end
-- find the closest block
-- * favor same plane
-- * going backwards only if the dest is above or below
local function closestPoint(reference, pts)
local lpt, lm -- lowest
for _,pt in pairs(pts) do
local m = Point.turtleDistance(reference, pt)
local h = Point.calculateHeading(reference, pt)
local t = Point.calculateTurns(reference.heading, h)
if pt.y ~= reference.y then -- try and stay on same plane
m = m + .01
end
if t ~= 2 or pt.y == reference.y then
m = m + t
if t > 0 then
m = m + .01
end
end
if not lm or m < lm then
lpt = pt
lm = m
end
end
return lpt
local lpt, lm -- lowest
for _,pt in pairs(pts) do
local m = Point.turtleDistance(reference, pt)
local h = Point.calculateHeading(reference, pt)
local t = Point.calculateTurns(reference.heading, h)
if pt.y ~= reference.y then -- try and stay on same plane
m = m + .01
end
if t ~= 2 or pt.y == reference.y then
m = m + t
if t > 0 then
m = m + .01
end
end
if not lm or m < lm then
lpt = pt
lm = m
end
end
return lpt
end
local function getAdjacentPoint(pt)
local t = { }
table.insert(t, pt)
for i = 0, 5 do
local hi = turtle.getHeadingInfo(i)
local heading
if i < 4 then
heading = (hi.heading + 2) % 4
end
table.insert(t, { x = pt.x + hi.xd, z = pt.z + hi.zd, y = pt.y + hi.yd, heading = heading })
end
local t = { }
table.insert(t, pt)
for i = 0, 5 do
local hi = turtle.getHeadingInfo(i)
local heading
if i < 4 then
heading = (hi.heading + 2) % 4
end
table.insert(t, { x = pt.x + hi.xd, z = pt.z + hi.zd, y = pt.y + hi.yd, heading = heading })
end
return closestPoint(turtle.getPoint(), t)
return closestPoint(turtle.getPoint(), t)
end
function turtle.level(startPt, endPt, firstPt, verbose)
checkedNodes = { }
nodes = { }
box = { }
checkedNodes = { }
nodes = { }
box = { }
box.x = math.min(startPt.x, endPt.x)
box.y = math.min(startPt.y, endPt.y)
box.z = math.min(startPt.z, endPt.z)
box.ex = math.max(startPt.x, endPt.x)
box.ey = math.max(startPt.y, endPt.y)
box.ez = math.max(startPt.z, endPt.z)
box.x = math.min(startPt.x, endPt.x)
box.y = math.min(startPt.y, endPt.y)
box.z = math.min(startPt.z, endPt.z)
box.ex = math.max(startPt.x, endPt.x)
box.ey = math.max(startPt.y, endPt.y)
box.ez = math.max(startPt.z, endPt.z)
if not Point.inBox(firstPt, box) then
error('Starting point is not in leveling area')
end
if not Point.inBox(firstPt, box) then
error('Starting point is not in leveling area')
end
if not turtle.pathfind(firstPt) then
error('failed to reach starting point')
end
if not turtle.pathfind(firstPt) then
error('failed to reach starting point')
end
turtle.set({
digPolicy = dig,
attackPolicy = 'attack',
movePolicy = 'moveAssured',
})
turtle.set({
digPolicy = dig,
attackPolicy = 'attack',
movePolicy = 'moveAssured',
})
oldCallback = turtle.getMoveCallback()
turtle.setMoveCallback(move)
oldCallback = turtle.getMoveCallback()
turtle.setMoveCallback(move)
repeat
local key = toKey(turtle.point)
repeat
local key = toKey(turtle.point)
checkedNodes[key] = true
nodes[key] = nil
checkedNodes[key] = true
nodes[key] = nil
dig(turtle.getAction('down'))
dig(turtle.getAction('up'))
dig(turtle.getAction('forward'))
dig(turtle.getAction('down'))
dig(turtle.getAction('up'))
dig(turtle.getAction('forward'))
if verbose then
print(string.format('%d nodes remaining', Util.size(nodes)))
end
if verbose then
print(string.format('%d nodes remaining', Util.size(nodes)))
end
if not next(nodes) then
break
end
if not next(nodes) then
break
end
local node = closestPoint(turtle.point, nodes)
node = getAdjacentPoint(node)
if not turtle.go(node) then
break
end
until turtle.isAborted()
local node = closestPoint(turtle.point, nodes)
node = getAdjacentPoint(node)
if not turtle.go(node) then
break
end
until turtle.isAborted()
turtle.resetState()
turtle.setMoveCallback(oldCallback)
turtle.resetState()
turtle.setMoveCallback(oldCallback)
end
return true

View File

@@ -18,12 +18,12 @@ local Runners = {
}
Equipper.equipLeft('minecraft:diamond_sword')
local scanner = Equipper.equipRight('plethora:module:2', 'plethora:scanner')
local scanner = Equipper.equipRight('plethora:scanner')
local facing = scanner.getBlockMeta(0, 0, 0).state.facing
turtle.point.heading = Point.facings[facing].heading
local sensor = Equipper.equipRight('plethora:module:3', 'plethora:sensor')
local sensor = Equipper.equipRight('plethora:sensor')
turtle.setMovementStrategy('goto')
turtle.set({ attackPolicy = 'attack' })
@@ -32,9 +32,9 @@ local function findChests()
if chest then
return { chest }
end
Equipper.equipRight('plethora:module:2', 'plethora:scanner')
Equipper.equipRight('plethora:scanner')
local chests = scanner.scan()
Equipper.equipRight('plethora:module:3', 'plethora:sensor')
Equipper.equipRight('plethora:sensor')
Util.filterInplace(chests, function(b)
if b.name == 'minecraft:chest' or

View File

@@ -12,238 +12,241 @@ local STARTUP_FILE = 'usr/autorun/farmer.lua'
local MIN_FUEL = 2500
local FUEL = Util.transpose {
'minecraft:coal:0',
'minecraft:coal:1',
'minecraft:blaze_rod:0',
'minecraft:coal:0',
'minecraft:coal:1',
'minecraft:blaze_rod:0',
}
local scanner = Equipper.equipRight('plethora:module:2', 'plethora:scanner')
local scanner = Equipper.equipRight('plethora:scanner')
local crops = Util.readTable(CONFIG_FILE) or {
['minecraft:wheat'] =
{ seed = 'minecraft:wheat_seeds', mature = 7, action = 'plant' },
['minecraft:carrots'] =
{ seed = 'minecraft:carrot', mature = 7, action = 'plant' },
['minecraft:potatoes'] =
{ seed = 'minecraft:potato', mature = 7, action = 'plant' },
['minecraft:beetroots'] =
{ seed = 'minecraft:beetroot_seeds', mature = 3, action = 'plant' },
['minecraft:nether_wart'] =
{ seed = 'minecraft:nether_wart', mature = 3, action = 'plant' },
['minecraft:cocoa'] =
{ seed = 'minecraft:dye:3', mature = 8, action = 'pick' },
['minecraft:reeds'] = { action = 'bash' },
['minecraft:chorus_flower'] = { action = 'bash' },
['minecraft:chorus_plant'] =
{ seed = 'minecraft:chorus_flower', mature = 0, action = 'bash-smash', },
['minecraft:melon_block'] = { action = 'smash' },
['minecraft:pumpkin'] = { action = 'smash' },
['minecraft:chest'] = { action = 'drop' },
['minecraft:cactus'] = { action = 'smash' },
['minecraft:wheat'] =
{ seed = 'minecraft:wheat_seeds', mature = 7, action = 'plant' },
['minecraft:carrots'] =
{ seed = 'minecraft:carrot', mature = 7, action = 'plant' },
['minecraft:potatoes'] =
{ seed = 'minecraft:potato', mature = 7, action = 'plant' },
['minecraft:beetroots'] =
{ seed = 'minecraft:beetroot_seeds', mature = 3, action = 'plant' },
['minecraft:nether_wart'] =
{ seed = 'minecraft:nether_wart', mature = 3, action = 'plant' },
['minecraft:cocoa'] =
{ seed = 'minecraft:dye:3', mature = 8, action = 'pick' },
['minecraft:reeds'] = { action = 'bash' },
['minecraft:chorus_flower'] = { action = 'bash' },
['minecraft:chorus_plant'] =
{ seed = 'minecraft:chorus_flower', mature = 0, action = 'bash-smash', },
['minecraft:melon_block'] = { action = 'smash' },
['minecraft:pumpkin'] = { action = 'smash' },
['minecraft:chest'] = { action = 'drop' },
['minecraft:cactus'] = { action = 'smash' },
}
if not fs.exists(CONFIG_FILE) then
Util.writeTable(CONFIG_FILE, crops)
Util.writeTable(CONFIG_FILE, crops)
end
if not fs.exists(STARTUP_FILE) then
Util.writeFile(STARTUP_FILE,
[[os.sleep(1)
Util.writeFile(STARTUP_FILE,
[[os.sleep(1)
shell.openForegroundTab('farmer.lua')]])
print('Autorun program created: ' .. STARTUP_FILE)
print('Autorun program created: ' .. STARTUP_FILE)
end
local retain = Util.transpose {
"minecraft:diamond_pickaxe",
"plethora:module:2",
"plethora:module:3",
"minecraft:diamond_pickaxe",
"plethora:module:2",
"plethora:module:3",
}
for _, v in pairs(crops) do
if v.seed then
retain[v.seed] = true
end
if v.seed then
retain[v.seed] = true
end
end
local function scan()
local blocks = scanner.scan()
local summed = turtle.getSummedInventory()
local doDropOff
local blocks = scanner.scan()
local summed = turtle.getSummedInventory()
local doDropOff
for _,v in pairs(summed) do
if v.count > 32 then
doDropOff = true
break
end
end
for _,v in pairs(summed) do
if v.count > 32 then
doDropOff = true
break
end
end
Util.filterInplace(blocks, function(b)
b.action = crops[b.name] and crops[b.name].action
Util.filterInplace(blocks, function(b)
b.action = crops[b.name] and crops[b.name].action
if b.action == 'bash' then
return b.y == 0
end
if b.action == 'drop' then
return doDropOff and (b.y == -1 or b.y == 1)
end
if b.action == 'bash-smash' then
if b.y == -1 then
b.action = 'smash'
end
if b.y == 0 then
b.action = 'bash'
end
return b.action ~= 'bash-smash'
end
if b.action == 'bash' then
return b.y == 0
end
if b.action == 'drop' then
return doDropOff and (b.y == -1 or b.y == 1)
end
if b.action == 'bash-smash' then
if b.y == -1 then
b.action = 'smash'
end
if b.y == 0 then
b.action = 'bash'
end
return b.action ~= 'bash-smash'
end
if b.action == 'smash' then
return b.y == -1
end
if b.action == 'pick' then
return b.y == 0 and b.state.age == 2
end
if b.action == 'bump' then
return b.y == 0
end
return b.action == 'plant' and
b.metadata == crops[b.name].mature and
b.y == -1
end)
if b.action == 'smash' then
return b.y == -1
end
if b.action == 'pick' then
return b.y == 0 and b.state.age == 2
end
if b.action == 'bump' then
return b.y == 0
end
if b.action == 'plant' and b.y == -1 then
if not b.metadata then -- minecraft 1.10
b = scanner.getBlockMeta(b.x, b.y, b.z)
end
return b.metadata == crops[b.name].mature
end
end)
local harvestCount = 0
for _,b in pairs(blocks) do
b.x = b.x + turtle.point.x
b.y = b.y + turtle.point.y
b.z = b.z + turtle.point.z
if b.action ~= 'drop' then
harvestCount = harvestCount + 1
end
end
local harvestCount = 0
for _,b in pairs(blocks) do
b.x = b.x + turtle.point.x
b.y = b.y + turtle.point.y
b.z = b.z + turtle.point.z
if b.action ~= 'drop' then
harvestCount = harvestCount + 1
end
end
return blocks, harvestCount
return blocks, harvestCount
end
local function harvest(blocks)
Equipper.equipRight('minecraft:diamond_pickaxe')
Equipper.equipRight('minecraft:diamond_pickaxe')
local dropped
local dropped
Point.eachClosest(turtle.point, blocks, function(b)
turtle.select(1)
Point.eachClosest(turtle.point, blocks, function(b)
turtle.select(1)
if b.action == 'bash' then
turtle.digForwardAt(b)
if b.action == 'bash' then
turtle.digForwardAt(b)
elseif b.action == 'drop' and not dropped then
if turtle.go(b.y == 1 and Point.below(b) or Point.above(b)) then
local dropFn = b.y == 1 and turtle.dropUp or turtle.dropDown
local dropDir = b.y == 1 and 'down' or 'up'
elseif b.action == 'drop' and not dropped then
if turtle.go(b.y == 1 and Point.below(b) or Point.above(b)) then
local dropFn = b.y == 1 and turtle.dropUp or turtle.dropDown
local dropDir = b.y == 1 and 'down' or 'up'
turtle.eachFilledSlot(function(slot)
if not retain[slot.name] and not retain[slot.key] then
turtle.select(slot.index)
dropFn()
end
end)
local summed = turtle.getSummedInventory()
for k,v in pairs(summed) do
if v.count > 16 then
dropFn(k, v.count - 16)
end
end
turtle.eachFilledSlot(function(slot)
if not retain[slot.name] and not retain[slot.key] then
turtle.select(slot.index)
dropFn()
end
end)
local summed = turtle.getSummedInventory()
for k,v in pairs(summed) do
if v.count > 16 then
dropFn(k, v.count - 16)
end
end
dropped = true
turtle.condense()
dropped = true
turtle.condense()
if turtle.getFuelLevel() < MIN_FUEL then
local inv = peripheral.wrap('bottom')
if inv and inv.list then
for k, v in pairs(inv.list()) do
if FUEL[table.concat({ v.name, v.damage }, ':')] then
local count = inv.pushItems(dropDir, k, v.count)
if count > 0 then
turtle.refuel(v.name, v.count)
print('Fuel: ' .. turtle.getFuelLevel())
break
end
end
end
end
end
end
if turtle.getFuelLevel() < MIN_FUEL then
local inv = peripheral.wrap('bottom')
if inv and inv.list then
for k, v in pairs(inv.list()) do
if FUEL[table.concat({ v.name, v.damage }, ':')] then
local count = inv.pushItems(dropDir, k, v.count)
if count > 0 then
turtle.refuel(v.name, v.count)
print('Fuel: ' .. turtle.getFuelLevel())
break
end
end
end
end
end
end
elseif b.action == 'smash' then
if turtle.digDownAt(b) then
if crops[b.name].seed then
turtle.placeDown(crops[b.name].seed)
end
end
elseif b.action == 'smash' then
if turtle.digDownAt(b) then
if crops[b.name].seed then
turtle.placeDown(crops[b.name].seed)
end
end
elseif b.action == 'plant' then
if turtle.digDownAt(b) then
turtle.placeDown(crops[b.name].seed)
end
elseif b.action == 'plant' then
if turtle.digDownAt(b) then
turtle.placeDown(crops[b.name].seed)
end
elseif b.action == 'bump' then
if turtle.faceAgainst(b) then
Equipper.equipRight('plethora:module:3', 'plethora:sensor')
os.sleep(.5)
-- search the ground for the dropped cactus
local sensed = peripheral.call('right', 'sense')
Equipper.equipRight('minecraft:diamond_pickaxe')
Util.filterInplace(sensed, function(s)
if s.displayName == 'item.tile.cactus' then
s.x = Util.round(s.x) + turtle.point.x
s.z = Util.round(s.z) + turtle.point.z
s.y = -1
if Point.distance(b, s) < 6 then
return true
end
end
end)
Point.eachClosest(turtle.point, sensed, function(s)
turtle.suckDownAt(s)
end)
end
elseif b.action == 'bump' then
if turtle.faceAgainst(b) then
Equipper.equipRight('plethora:sensor')
os.sleep(.5)
-- search the ground for the dropped cactus
local sensed = peripheral.call('right', 'sense')
Equipper.equipRight('minecraft:diamond_pickaxe')
Util.filterInplace(sensed, function(s)
if s.displayName == 'item.tile.cactus' then
s.x = Util.round(s.x) + turtle.point.x
s.z = Util.round(s.z) + turtle.point.z
s.y = -1
if Point.distance(b, s) < 6 then
return true
end
end
end)
Point.eachClosest(turtle.point, sensed, function(s)
turtle.suckDownAt(s)
end)
end
elseif b.action == 'pick' then
local h = Point.facings[b.state.facing].heading
local hi = Point.headings[(h + 2) % 4] -- opposite heading
elseif b.action == 'pick' then
local h = Point.facings[b.state.facing].heading
local hi = Point.headings[(h + 2) % 4] -- opposite heading
-- without pathfinding, will be unable to circle log
if turtle.go({ x = b.x + hi.xd, z = b.z + hi.zd, heading = h }) then
if turtle.dig() then
turtle.place(crops[b.name].seed)
end
end
end
end)
Equipper.equipRight('plethora:module:2', 'plethora:scanner')
-- without pathfinding, will be unable to circle log
if turtle.go({ x = b.x + hi.xd, z = b.z + hi.zd, heading = h }) then
if turtle.dig() then
turtle.place(crops[b.name].seed)
end
end
end
end)
Equipper.equipRight('plethora:scanner')
end
local s, m = turtle.run(function()
local facing = scanner.getBlockMeta(0, 0, 0).state.facing
turtle.point.heading = Point.facings[facing].heading
local facing = scanner.getBlockMeta(0, 0, 0).state.facing
turtle.point.heading = Point.facings[facing].heading
turtle.setStatus('farming')
print('Fuel: ' .. turtle.getFuelLevel())
turtle.setStatus('farming')
print('Fuel: ' .. turtle.getFuelLevel())
turtle.setMovementStrategy('goto')
repeat
local blocks, harvestCount = scan()
if harvestCount > 0 then
turtle.setStatus('Harvesting')
harvest(blocks)
turtle.setStatus('Sleeping')
end
os.sleep(10)
if turtle.getFuelLevel() < 10 then
turtle.setStatus('Out of fuel')
error('Out of fuel')
end
until turtle.isAborted()
turtle.setMovementStrategy('goto')
repeat
local blocks, harvestCount = scan()
if harvestCount > 0 then
turtle.setStatus('Harvesting')
harvest(blocks)
turtle.setStatus('Sleeping')
end
os.sleep(10)
if turtle.getFuelLevel() < 10 then
turtle.setStatus('Out of fuel')
error('Out of fuel')
end
until turtle.isAborted()
end)
if not s and m then
error(m)
error(m)
end

View File

@@ -9,8 +9,9 @@ Requirements
* Standard Modem
* Block Scanner
* Entity Sensor
* Crafting Table
* Furnace
* Vanilla Chest
* Sapling
* GPS
Setup
@@ -19,18 +20,20 @@ Setup
> package install farms
> reboot
The turtle will need some fuel initially.
The tree farm fits exactly in one chunk. It's best to have a mostly level ground around the center of the farming area as the turtle will only collect saplings that have fallen to the same level as the turtle.
To align the turtle perfectly in one chunk, position the turtle 8 blocks diagonally from the bottom left corner.
Place a sapling directly in front of the turtle and place all the required items into the inventory.
Place all the required items into the inventory.
To start the program, run:
> superTreefarm
A startup file is created automatically the first time the program is run (usr/autorun/superTreefarm.lua).
If the turtle does not get any saplings from the initial tree, place down another sapling in front of the turtle.
If the turtle does not get any saplings from the initial tree, another sapling in the turtle.
Tips
====

View File

@@ -10,111 +10,117 @@ local turtle = _G.turtle
local STARTUP_FILE = 'usr/autorun/rancher.lua'
local retain = Util.transpose {
'minecraft:shears',
'minecraft:wheat',
'minecraft:diamond_sword',
'plethora:module:3',
'minecraft:shears',
'minecraft:wheat',
'minecraft:diamond_sword',
'plethora:module:3',
}
local config = {
animal = 'Cow',
max_animals = 15,
animal = 'Cow',
max_animals = 15,
}
Config.load('rancher', config)
local ANIMALS = {
Pig = { min = 0, food = 'minecraft:carrot' },
Sheep = { min = .5, food = 'minecraft:wheat' },
Cow = { min = .5, food = 'minecraft:wheat' },
Pig = { min = 0, food = 'minecraft:carrot' },
Sheep = { min = .5, food = 'minecraft:wheat' },
Cow = { min = .5, food = 'minecraft:wheat' },
}
local animal = ANIMALS[config.animal]
Equipper.equipLeft('minecraft:diamond_sword')
local sensor = Equipper.equipRight('plethora:module:3', 'plethora:sensor')
local sensor = Equipper.equipRight('plethora:sensor')
local chest = Adapter({ side = 'bottom', direction = 'up' }) or error('missing chest')
if not fs.exists(STARTUP_FILE) then
Util.writeFile(STARTUP_FILE,
[[os.sleep(1)
Util.writeFile(STARTUP_FILE,
[[os.sleep(1)
shell.openForegroundTab('rancher.lua')]])
print('Autorun program created: ' .. STARTUP_FILE)
print('Autorun program created: ' .. STARTUP_FILE)
end
local function getAnimalCount()
local blocks = sensor.sense()
local blocks = sensor.sense()
local grown = 0
local babies = 0
local grown = 0
local babies = 0
Util.filterInplace(blocks, function(v)
if v.name == config.animal then
if v.y > -.5 then grown = grown + 1 end
if v.y < -.5 then babies = babies + 1 end
return v.y > -.5
end
end)
Util.filterInplace(blocks, function(v)
if v.name == config.animal then
local entity = sensor.getMetaByID(v.id)
if entity then
if entity.isChild then
babies = babies + 1
else
grown = grown + 1
end
return not entity.isChild
end
end
end)
Util.print('%d grown, %d babies', grown, babies)
Util.print('%d grown, %d babies', grown, babies)
return #blocks
return #blocks
end
local function butcher()
Equipper.equipRight('minecraft:diamond_sword')
turtle.select(1)
Equipper.equipRight('minecraft:diamond_sword')
turtle.select(1)
turtle.attack()
for _ = 1, 3 do
turtle.turnRight()
turtle.attack()
end
Equipper.equipRight('plethora:module:3', 'plethora:sensor')
turtle.attack()
for _ = 1, 3 do
turtle.turnRight()
turtle.attack()
end
Equipper.equipRight('plethora:sensor')
turtle.eachFilledSlot(function(slot)
if not retain[slot.name] then
chest:insert(slot.index, 64)
end
end)
turtle.eachFilledSlot(function(slot)
if not retain[slot.name] then
chest:insert(slot.index, 64)
end
end)
end
local function breed()
turtle.select(1)
turtle.select(1)
if config.animal == 'Sheep' then
turtle.place('minecraft:shears')
end
turtle.place('minecraft:wheat')
for _ = 1, 3 do
turtle.turnRight()
if config.animal == 'Sheep' then
turtle.place('minecraft:shears')
end
turtle.place('minecraft:wheat')
end
if config.animal == 'Sheep' then
turtle.place('minecraft:shears')
end
turtle.place('minecraft:wheat')
for _ = 1, 3 do
turtle.turnRight()
if config.animal == 'Sheep' then
turtle.place('minecraft:shears')
end
turtle.place('minecraft:wheat')
end
end
local s, m = turtle.run(function()
print('Configured animal: ' .. config.animal)
print('Configured animal: ' .. config.animal)
repeat
local animalCount = getAnimalCount()
if animalCount > config.max_animals then
turtle.setStatus('Butchering')
butcher()
elseif turtle.getItemCount(animal.food) == 0 then
if chest:provide({ name = animal.food, damage = 0 }, 64) == 0 then
print('Out of ' .. animal.food)
turtle.setStatus('Out of food')
end
else
turtle.setStatus('Breeding')
breed()
end
os.sleep(5)
until turtle.isAborted()
repeat
local animalCount = getAnimalCount()
if animalCount > config.max_animals then
turtle.setStatus('Butchering')
butcher()
elseif turtle.getItemCount(animal.food) == 0 then
if chest:provide({ name = animal.food, damage = 0 }, 64) == 0 then
print('Out of ' .. animal.food)
turtle.setStatus('Out of food')
end
else
turtle.setStatus('Breeding')
breed()
end
os.sleep(5)
until turtle.isAborted()
end)
if not s and m then
error(m)
error(m)
end

View File

@@ -11,7 +11,7 @@ local STARTUP_FILE = 'usr/autorun/spawner.lua'
local mobTypes = { }
Equipper.equipLeft('minecraft:diamond_sword')
local scanner = Equipper.equipRight('plethora:module:2', 'plethora:scanner')
local scanner = Equipper.equipRight('plethora:scanner')
turtle.reset()
local facing = scanner.getBlockMeta(0, 0, 0).state.facing
@@ -28,13 +28,13 @@ Util.filterInplace(data, function(b)
end)
local chest = Point.closest(spawner, data) or error('missing drop off chest')
local sensor = Equipper.equipRight('plethora:module:3', 'plethora:sensor')
local sensor = Equipper.equipRight('plethora:sensor')
if not fs.exists(STARTUP_FILE) then
Util.writeFile(STARTUP_FILE,
string.format([[os.sleep(1)
Util.writeFile(STARTUP_FILE,
string.format([[os.sleep(1)
shell.openForegroundTab('spawner.lua %s')]], table.concat({ ... }, ' ')))
print('Autorun program created: ' .. STARTUP_FILE)
print('Autorun program created: ' .. STARTUP_FILE)
end
turtle.setMovementStrategy('goto')
@@ -70,8 +70,8 @@ local function normalize(b)
b.z = Util.round(b.z) + turtle.point.z
return b.x >= spawner.x - 4 and b.x <= spawner.x + 4 and
b.y >= spawner.y - 4 and b.y <= spawner.y + 4 and
b.z >= spawner.z - 4 and b.z <= spawner.z + 4
b.y >= spawner.y - 4 and b.y <= spawner.y + 4 and
b.z >= spawner.z - 4 and b.z <= spawner.z + 4
end
local function aboveAttack(b)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff