Last active
November 5, 2015 03:25
-
-
Save Ricket/e4da3beb2b7f6505b522 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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