Skip to content

Instantly share code, notes, and snippets.

@Ricket
Last active November 5, 2015 03:25
Show Gist options
  • Save Ricket/e4da3beb2b7f6505b522 to your computer and use it in GitHub Desktop.
Save Ricket/e4da3beb2b7f6505b522 to your computer and use it in GitHub Desktop.
local blocksToBreak = {
"essentialcraft:oreDrops", "GalacticraftCore:tile.gcBlockCore",
"appliedenergistics2:tile.OreQuartzCharged", "denseores:block1"
}
local sides = require("sides")
local inputSide = sides.bottom
local outputSide = sides.top
local component = require("component")
if not component.isAvailable("robot") then
io.stderr:write("can only run on robots")
return
end
local r = component.robot
local invcon = component.inventory_controller
-- return true if in front of the robot is not air
local function somethingInTheWay()
local _, what = r.detect(sides.front)
return (what ~= "air")
end
-- return true if given item name is one to be placed and broken
local function isBlockToBreak(itemName)
for _, name in ipairs(blocksToBreak) do
if itemName == name then
return true
end
end
return false
end
-- search the input inventory for a block to break, put it into slot 2 and return true,
-- or return false if no block found
local function retrieveBlock()
r.select(2)
local myStack2 = invcon.getStackInInternalSlot(2)
if myStack2 ~= nil then
if isBlockToBreak(myStack2["name"]) then
-- print("already have block")
return true
else
print("Unknown item in slot 2")
return false
end
end
-- now slot 2 is empty and selected
local inputSize = invcon.getInventorySize(inputSide)
if inputSize == nil then
print("No inventory below me")
return false
end
local slot = 1
local stack = nil
while slot <= inputSize do
stack = invcon.getStackInSlot(inputSide, slot)
if stack ~= nil and isBlockToBreak(stack["name"]) then
break
else
slot = slot + 1
end
end
if stack == nil then
print("None of the inventory slots have a block to break")
return false
end
print("I found a " .. stack["name"] .. " in slot " .. slot)
invcon.suckFromSlot(inputSide, slot)
myStack2 = invcon.getStackInInternalSlot(2)
if not isBlockToBreak(myStack2["name"]) then
print("Bait and switch! I thought I got a " .. stack["name"] .. " but instead I got a " .. myStack2["name"])
-- just keep it, it'll get deposited to output on next run
return false
else
print("I obtained the " .. myStack2["name"])
return true
end
end
-- replenish pickaxe from input inventory
local function replenishPickaxe()
local toolslot, _, _ = r.durability()
if toolslot ~= nil then
-- print("already have pickaxe")
return true
end
print("I need a diamond pickaxe")
if invcon.getInventorySize(inputSide) == nil then
print("No inventory below me")
return false
end
local slot = 1
while true do
local stack = invcon.getStackInSlot(inputSide, slot)
if stack == nil then
print("None of the inventory slots have a diamond pickaxe")
return false
end
if stack["name"] == "minecraft:diamond_pickaxe" then
break
else
slot = slot + 1
end
end
print("I found a diamond pickaxe in slot " .. slot)
r.select(1)
invcon.suckFromSlot(inputSide, slot)
local myStack1 = invcon.getStackInInternalSlot(1)
if myStack1["name"] ~= "minecraft:diamond_pickaxe" then
print("Bait and switch! I thought I got a pickaxe but instead I got a " .. myStack1["name"])
-- drop it
r.drop(sides.front)
return false
end
-- now we have a diamond pickaxe in slot 1, just need to equip it
invcon.equip()
print("I equipped the diamond pickaxe")
return true
end
-- checks slot 2 for non-block items; if any, deposits them into the output side
-- returns true if slot 2 is already empty or has been deposited, or it's a breakable block
-- returns false for error such as output inventory full or missing
local function depositObtainedItems()
r.select(2)
local myStack2 = invcon.getStackInInternalSlot(2)
if myStack2 == nil or isBlockToBreak(myStack2["name"]) then
-- nothing to deposit
return true
end
print("Depositing items: " .. myStack2["size"] .. " " .. myStack2["name"])
local outputSize, outputErr = invcon.getInventorySize(outputSide)
if outputSize == nil then
print("Output error: " .. outputErr)
return false
end
local slot = 1
while true do
local stack = invcon.getStackInSlot(outputSide, slot)
if stack == nil or stack["name"] == myStack2["name"] then
local dropped = invcon.dropIntoSlot(outputSide, slot)
-- it is possible that the items aren't actually the same (same name, different metadata)
-- so in that case drop returns false, we will not return and instead will keep looping
if dropped then return true end
end
slot = slot + 1
if slot > outputSize then
print("No free output slots")
return false
end
end
end
-- ensure we have a pickaxe, obtain a block, place it, break it, pick up the pieces, deposit into the output side
-- if all goes well, return true which means immediately do it again
-- if there's a problem, return false which means maybe wait a bit before retrying
local function placeAndBreak()
-- ensure we have a pickaxe
local hasPickaxe = replenishPickaxe()
if not hasPickaxe then return false end
-- ensure slot 2 is empty or already has a breakable block in it
local preDepositedItems = depositObtainedItems()
if not preDepositedItems then return false end
-- retrieve a breakable block
local hasBlock = retrieveBlock()
if not hasBlock then return false end
-- ensure there is nothing in front of me
if somethingInTheWay() then
print("There is something in the way, can't place the block")
return false
end
-- place the block
r.select(2)
local placedBlock = r.place(sides.front)
if not placedBlock then
print("Couldn't place the block")
return false
end
-- now mine the block in front of me (it obtains the mined items)
local minedBlock = r.swing(sides.front)
if not minedBlock then
print("Couldn't mine the block")
return false
end
local depositedItems = depositObtainedItems()
if not depositedItems then
print("Couldn't deposit the mined items")
return false
end
-- all done!
return true
end
while true do
local success = placeAndBreak()
if success then
print("Success, iterating again")
else
print("Sleeping 3 seconds and retrying")
os.sleep(3)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment