Last active
March 2, 2021 17:57
Work in progress mining turtle script for ComputerCraft Tweaked 1.12.2
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
--[[ | |
newmine.lua | |
kyle1elyk 2021-02-27 | |
CraftOS 1.8 | |
Uses: mpeterv/argparse (with minor conversion to CraftOS 1.8) | |
https://raw.githubusercontent.com/mpeterv/argparse/master/src/argparse.lua | |
]] | |
--[Current Position] | |
local curPos, curDir = vector.new(0, 0, 0), 0 | |
--[Initial Position and Direction] | |
local iniPos, iniDir = vector.new(0, 0, 0), 0 | |
inventory = {} | |
inventoryNamed = {} | |
local status = "Not Set." | |
local facing = {[0] = "South", "West", "North", "East"} | |
local mineLevel, mineHeight, corridorLength, branchLength = 0, 0, 0, 0 | |
local useRednet = false | |
local rednetTarget = nil | |
local includesList, excludesList = nil, nil | |
local reportAllOre, excludeTrashBlocks = nil, nil | |
local argparse = require "argparse" | |
--[Setting up argument parsing] | |
local parser = argparse("newmine", "Mining program by kyle1elyk") | |
parser:option("-l --mine-level", "Mine Level", 12) | |
parser:option("-m --mine-height", "Mine Height", 3) | |
parser:option("-c --corridor-length", "Corridor Length", 16) | |
parser:option("-b --branch-length", "Branch Length", 16) | |
parser:option("-d --direction", "Initial direction", 0) | |
parser:mutex( | |
parser:option("-p --pos", "Start Position", {0,0,0}) :args(3), | |
parser:flag("--gps", "GPS Position") | |
) | |
parser:option("-r --rednet", "Enable rednet, b for broadcast") | |
parser:mutex( | |
parser:option("-e --exclude", "Exclude blocks to be mined") :args("+"), | |
parser:option("-i --include", "Seek blocks to be mined") :args("+") | |
) | |
local args = parser:parse() | |
--[End argument parsing setup] | |
term.clear() | |
term.setCursorPos(0, 0) | |
function cloneVector(v) | |
return vector.new(v.x,v.y,v.z) | |
end | |
--[Handle Rednet flag] | |
local function getModemSide() | |
local sides = {"left", "right"} | |
for i, side in ipairs(sides) do | |
if peripheral.getType(side) == "modem" then | |
return side | |
end | |
end | |
end | |
if args.rednet then | |
local side = peripheral.find("modem") | |
if side then | |
if args.rednet == "b" then | |
rednetTarget = nil | |
elseif isnumber(args.rednet) then | |
rednetTarget = isnumber(args.rednet) | |
else | |
error("Invalid Rednet Target") | |
end | |
rednet.open(getModemSide()) | |
useRednet = true | |
print("Using Rednet") | |
else | |
error("No Modem, can not use Rednet") | |
end | |
else | |
print("No rednet") | |
end | |
--[Handle position argument] | |
if not args.gps then | |
local x,y,z = unpack(args.pos) | |
if string.sub(x, 1, 1) == "_" then x = "-" .. string.sub(x, 2) end | |
if string.sub(y, 1, 1) == "_" then y = "-" .. string.sub(y, 2) end | |
if string.sub(z, 1, 1) == "_" then z = "-" .. string.sub(z, 2) end | |
curPos = vector.new(tonumber(x), tonumber(y), tonumber(z)) | |
else | |
local x,y,z = gps.locate() | |
if not x then | |
error("Failed to get GPS") | |
end | |
curPos = vector.new(x,y,z) | |
end | |
--[Handle Direction argument] | |
if tonumber(args.direction) then | |
local d = tonumber(args.direction) | |
if d >= 0 and d < 4 then | |
curDir = d | |
else | |
error("Direction must be 0 to 3") | |
end | |
else | |
local c = string.lower(string.sub(args.direction, 1, 1)) | |
if c == "s" then | |
curDir = 0 | |
elseif c == "w" then | |
curDir = 1 | |
elseif c == "n" then | |
curDir = 2 | |
elseif c == "e" then | |
curDir = 3 | |
else | |
error("Invalid direction") | |
end | |
end | |
print("Position set to", curPos, "facing", facing[curDir]) | |
iniPos = cloneVector(curPos) | |
iniDir = curDir | |
--[Handle Include/Exclude list] | |
if args.include then | |
includesList = {} | |
print("Only reporting:") | |
for i, block in ipairs(args.include) do | |
if block == "ore" then | |
reportAllOre = true | |
else | |
includesList[block] = block | |
io.write(block, " ") | |
end | |
end | |
elseif args.exclude then | |
excludesList = {} | |
print("Reporting everything, except:") | |
for i, block in ipairs(args.exclude) do | |
if block == "trash" then | |
excludeTrashBlocks = true | |
else | |
excludesList[block] = block | |
io.write(block, " ") | |
end | |
end | |
end | |
print() | |
mineLevel = tonumber(args.mine_level) or error("Mine Level is not a number") | |
mineHeight = tonumber(args.mine_height) or error("Mine Height is not a number") | |
corridorLength = tonumber(args.corridor_length) or error("Corridor Length is not a number") | |
branchLength = tonumber(args.branch_length) or error("Branch Length is not a number") | |
print("Mining at", mineLevel) | |
print("Tunnel Height", mineHeight) | |
print("Corridor length", corridorLength) | |
print("Branch Height", branchLength) | |
--[[ | |
TURTLE FUNCTIONS | |
--]] | |
function syncInventory() | |
local differences = {} | |
inventoryNamed = {} | |
for i=16, 1, -1 do | |
local thisItemSlot = turtle.getItemDetail(i) | |
if inventory[i] and thisItemSlot then | |
if inventory[i].name ~= thisItemSlot.name or inventory[i].count ~= thisItemSlot.count or inventory[i].damage ~= thisItemSlot.damage then | |
table.insert(differences, i) | |
end | |
elseif inventory[i] ~= thisItemSlot then | |
table.insert(differences, i) | |
end | |
inventory[i] = thisItemSlot | |
if thisItemSlot then | |
inventoryNamed[thisItemSlot.name] = i | |
end | |
end | |
return differences | |
end | |
function waitOnFuel(amount) -- [This function is blocking until inventory changes] | |
amount = amount or 1 | |
local fuel = { | |
["minecraft:coal"] = 80, | |
["minecraft:coal_block"] = 800, | |
["minecraft:lava_bucket"] = 1000 | |
} | |
fueled = 0 | |
while fueled < amount do | |
for i=1, 16 do | |
if turtle.getItemCount(i) > 0 then | |
local itemName = turtle.getItemDetail(i).name | |
if fuel[itemName] then | |
local halfStack = math.min(turtle.getItemCount(i), math.ceil((amount - fueled) / fuel[itemName])) | |
fueled = fueled + fuel[itemName] * halfStack | |
turtle.select(i) | |
turtle.refuel(halfStack) | |
print ("Fueled", fuel[itemName] * halfStack, "with", halfStack,itemName) | |
if fueled < amount then | |
print ("Waiting on", amount - fueled , "fuel") | |
end | |
break | |
end | |
end | |
end | |
if fueled < amount then | |
print ("Waiting on", amount, "fuel") | |
os.pullEvent("turtle_inventory") | |
end | |
end | |
end | |
function forward(n, noDig) | |
if n and n < 0 then return back(-n, noDig) end | |
for i=1, n or 1 do | |
if turtle.getFuelLevel() < 1 then | |
waitOnFuel() | |
end | |
if not turtle.forward() then | |
repeat | |
if not noDig then turtle.dig() end | |
turtle.attack() | |
until turtle.forward() | |
end | |
if curDir == 0 then | |
curPos.z = curPos.z + 1 | |
elseif curDir == 1 then | |
curPos.x = curPos.x - 1 | |
elseif curDir == 2 then | |
curPos.z = curPos.z - 1 | |
elseif curDir == 3 then | |
curPos.x = curPos.x + 1 | |
end | |
end | |
return true | |
end | |
function up(n, noDig) | |
if n and n < 0 then return down(-n, noDig) end | |
for i=1, n or 1 do | |
if turtle.getFuelLevel() < 1 then | |
waitOnFuel() | |
end | |
if not turtle.up() then | |
repeat | |
if not noDig then turtle.digUp() end | |
turtle.attackUp() | |
until turtle.up() | |
end | |
curPos.y = curPos.y + 1 | |
end | |
return true | |
end | |
function down(n, noDig) | |
if n and n < 0 then return up(-n, noDig) end | |
for i=1, n or 1 do | |
if turtle.getFuelLevel() < 1 then | |
waitOnFuel() | |
end | |
if not turtle.down() then | |
repeat | |
if not noDig then turtle.digDown() end | |
turtle.attackDown() | |
until turtle.down() | |
end | |
curPos.y = curPos.y - 1 | |
end | |
return true | |
end | |
function turnRight(n) --[turns Right n times] | |
n = n or 1 | |
if n and n < 0 then return turnLeft(-n) end | |
for i=n,1,-1 do | |
turtle.turnRight() | |
curDir = curDir + 1 | |
if curDir == 4 then curDir = 0 end | |
end | |
end | |
function turnLeft(n) --[Turns left n times] | |
n = n or 1 | |
if n and n < 0 then return turnRight(-n) end | |
for i=n,1,-1 do | |
turtle.turnLeft() | |
curDir = curDir - 1 | |
if curDir == -1 then curDir = 3 end | |
end | |
end | |
function dig() | |
turtle.dig() | |
end | |
-- forward(1, true) | |
-- turnLeft() | |
-- turnLeft(2) | |
-- turnRight(-1) -> turnLeft(1) | |
function mine() | |
local branches = math.ceil(corridorLength / 3) | |
local cycles = math.ceil(branches / 2) | |
local branch = 0 | |
forward() -- TODO: uncomment | |
local mineStartPos, mineDir = cloneVector(curPos), curDir | |
function atCorridorEnd(n, db) | |
n = n or 0 | |
local checkVal = nil | |
local endX, endZ = curPos.x, curPos.z | |
if curDir == 0 then | |
endZ = endZ + n | |
elseif curDir == 1 then | |
endX = endX - n | |
elseif curDir == 2 then | |
endZ = endZ - n | |
elseif curDir == 3 then | |
endX = endX + n | |
end | |
if mineDir == 0 then | |
checkVal = mineStartPos.z + (corridorLength - 1) | |
return endZ >= checkVal | |
elseif mineDir == 1 then | |
checkVal = mineStartPos.x - (corridorLength - 1) | |
return endX <= checkVal | |
elseif mineDir == 2 then | |
checkVal = mineStartPos.z - (corridorLength - 1) | |
return endZ <= checkVal | |
elseif mineDir == 3 then | |
checkVal = mineStartPos.x + (corridorLength - 1) | |
return endX >= checkVal | |
end | |
end | |
function atCorridorStart() | |
if mineDir % 2 == 0 then | |
return curPos.z == mineStartPos.z | |
else | |
return curPos.x == mineStartPos.x | |
end | |
end | |
function atBottom() | |
return curPos.y == mineStartPos.y | |
end | |
function atTop() | |
return curPos.y == mineStartPos.y + mineHeight - 1 | |
end | |
local placeTorch = 0 | |
function digWallInfront() | |
local goUp = atBottom() | |
dig() | |
if goUp then | |
while not atTop() do | |
up() | |
repeat | |
dig() | |
os.sleep(0.15) | |
until not turtle.detect() | |
end | |
else | |
while not atBottom() do | |
down() | |
repeat | |
dig() | |
os.sleep(0.15) | |
until not turtle.detect() | |
end | |
syncInventory() | |
local torchSlot = inventoryNamed["minecraft:torch"] | |
if torchSlot and turtle.getItemCount(torchSlot) > 0 and turtle.getItemDetail(torchSlot).name:find("torch") then | |
if placeTorch <= 0 then | |
turtle.digUp() | |
turtle.select(torchSlot) | |
if turtle.placeUp() then | |
placeTorch = 2 | |
end | |
turtle.select(1) | |
else | |
placeTorch = placeTorch - 1 | |
end | |
end | |
end | |
end | |
function digBranch() | |
branch = branch + 1 | |
print("Branch", branch, "/", branches) | |
if branchLength % 2 == 1 then | |
digWallInfront() | |
forward() | |
end | |
for iBranch=1, math.floor(branchLength / 2) do | |
digWallInfront() | |
forward(2) | |
end | |
end | |
-- print(atCorridorStart(), atCorridorEnd()) | |
-- forward(1, true) | |
-- print(atCorridorStart(), atCorridorEnd()) | |
-- forward(1, true) | |
-- print(atCorridorStart(), atCorridorEnd()) | |
-- digWallInfront() | |
-- forward(2) | |
-- digWallInfront() | |
local branchFuelCost = (branchLength * mineHeight) - ((mineHeight - 1) * math.floor((branchLength - 1) / 2 )) | |
local cycleFuelCost = (2 * branchFuelCost) + (2 * (mineHeight - 1) + 3) | |
for cycle=1, cycles do | |
if (cycleFuelCost > turtle.getFuelLevel()) then | |
waitOnFuel(cycleFuelCost - turtle.getFuelLevel()) | |
end | |
-- if not at corridor end | |
-- mine main corridor ahead | |
if not atCorridorEnd() then | |
digWallInfront() | |
end | |
-- turn left and go to end | |
turnLeft() | |
digBranch() | |
-- turn left to mine behind if not at corridor start | |
if not atCorridorStart() then | |
turnLeft() | |
digWallInfront() | |
turnRight() | |
end | |
-- [facing away from corridor here] | |
-- if not corridor end | |
-- go to next branch location | |
-- mine ahead | |
turnRight() | |
if not atCorridorEnd(2) then | |
digWallInfront() | |
forward(2) | |
digWallInfront() | |
forward() | |
if not atCorridorEnd() then | |
digWallInfront() | |
end | |
turnRight() | |
else | |
turnRight() | |
end | |
-- [facing corridor here] | |
-- head back to main corridor | |
digBranch() | |
-- mine behind in main corridor | |
turnRight() | |
digWallInfront() | |
turnLeft() | |
-- if not corridor end | |
-- go to next branch location | |
turnLeft() | |
for i=1,3 do | |
if not atCorridorEnd() then | |
digWallInfront() | |
forward() | |
end | |
end | |
end | |
--[[for i=1, mineHeight - 2 do | |
print(corridorLength, branches) | |
end]] | |
end | |
mine() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment