Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local status = {
- "Waiting for Input",
- "Mining",
- "Not enough fuel",
- --"Returning Home", -- Not yet implemented
- --"Storing Items", -- Not yet implemented
- }
- local function tableContainsKey(t, key)
- for k, v in pairs(t) do
- if k == key then return true end
- end
- return false
- end
- local function right(orientation)
- turtle.turnRight()
- return orientation + 1 % 4
- end
- local function turnTowardsTargetOrientation(orientation, target_orientation)
- repeat orientation = right(orientation) until orientation == target_orientation
- return target_orientation
- end
- local function printProgramInfo()
- term.clear()
- term.setCursorPos(1, 1)
- term.write("Miner MkI")
- end
- local function printStatus(status, position, current_fuel, needed_fuel, lower, upper, width, length)
- term.setCursorPos(1, 2)
- term.clearLine()
- term.write(status)
- end
- local function endPosition(starting_position, lower, upper, width, length)
- local sx, sy, sz = starting_position[1], starting_position[2], starting_position[3]
- local z = sz
- if width % 2 ~= 0 then
- z = z + length
- end
- return sx, upper, z
- end
- local function neededFuel(lower, upper, width, length)
- return width * length * (upper - lower) -- the total area
- + math.max(length, width) -- plus a little extra to maneuver around obstacles
- end
- local function endPositionForLevel(starting_position, width, length)
- return endPosition(starting_position, nil, 0, width, length)
- end
- local function endPositionForLevel(starting_position, length)
- return starting_position[3] == length
- end
- local function offset(orientation)
- if orientation == 0 then
- return 1
- elseif orientation == 2 then
- return -1
- end
- end
- local function orientationVec(orientation)
- if orientation == 0 then
- return vector.new(1, 0, 0)
- elseif orientation == 1 then
- return vector.new(0, 0, 1)
- elseif orientation == 2 then
- return vector.new(-1, 0, 0)
- elseif orientation == 3 then
- return vector.new(0, 0, -1)
- else
- error("[ERROR] (orientationVec) orientation is invalid (not 0..4)")
- end
- end
- local function forward(position, orientation)
- turtle.forward()
- local pos_vec = vector.new(position[1], position[2], position[3])
- local res = pos_vec + orientationVec(orientation)
- return {res.x, res.y, res.z}
- end
- local function returnToStartPositionForLevel(position, orientation, width, length)
- orientation = turnTowardsTargetOrientation(orientation, 3)
- repeat position = forward(position, orientation) until position[3] == 0
- orientation = turnTowardsTargetOrientation(orientation, 2)
- repeat position = forward(position, orientation) until position[1] == 0
- orientation = turnTowardsTargetOrientation(orientation, 0)
- return position, orientation
- end
- local function up(position)
- turtle.digUp()
- turtle.up()
- return {position[1], position[2] + 1, position[3]}
- end
- local function shouldMineBlock(details)
- return not tableContainsKey(details.tags, "forge:ores")
- end
- local function mineBlock(position, orientation)
- local is_block, details = turtle.inspect()
- if is_block then
- if shouldMineBlock(details) then
- turtle.dig()
- else
- moveAroundObstacle(position, orientation)
- end
- end
- end
- -- orientation works like this
- -- 0 +l
- -- 1 +w
- -- 2 -l
- -- 3 -w
- local function move(position, orientation, lower, upper, width, length)
- print(position[1] .." ".. position[3])
- if position[2] < upper then
- if position[3] < width then
- if position[1] < length then
- position = forward(position, orientation)
- else
- orientation = turnTowardsTargetOrientation(orientation, 1)
- mineBlock(position, orientation)
- position = forward(position, orientation)
- orientation = turnTowardsTargetOrientation(orientation, 2)
- end
- else
- position, orientation = returnToStartPositionForLevel(position, orientation, width, length)
- position = up(position)
- end
- end
- print(position[1] .." ".. position[3])
- return position
- end
- local function moveAroundObstacle(position, orientation)
- error("[ERROR] (moveAroundObstacle) not yet implemented")
- end
- -- Mines an area, leaving ores or gems as is.
- -- That means that (for example) cobblestone and gravel will be mined,
- -- but not iron ore or redstone.
- --
- -- The area looks like this:
- -- T (looking towards length)
- -- ┌-------> width
- -- |
- -- |
- -- |
- -- v
- -- length
- --
- -- and lower and upper represent the y-levels the turtle should mine between.
- --
- -- Position refers to where the turtle is, but may be omitted in which case position will be set
- -- assuming the turtle is at y-level lower.
- -- Length will then be how many steps the turtle will go forward for.
- local function mine(status, position, orientation, lower, upper, width, length)
- if lower == nil then
- error("[ERROR] (mine) lower must not be nil here!")
- end
- local current_fuel = turtle.getFuelLevel()
- local needed_fuel = neededFuel(lower, upper, width, length)
- if position == nil then
- position = {0, lower, 0}
- end
- if orientation == nil then
- orientation = 0
- end
- while position ~= endPosition(position, lower, upper, width, length) do
- printStatus(status[2], position, current_fuel, needed_fuel, lower, upper, width, length)
- mineBlock(position, orientation)
- position = move(position, orientation, lower, upper, width, length)
- end
- end
- local function askForHeightRange()
- term.clearLine()
- term.setCursorPos(1, 5)
- term.write("Please enter the lower y-level: ")
- local lower = nil
- repeat lower = tonumber(io.read()) until lower ~= nil
- term.clearLine()
- term.setCursorPos(1, 5)
- term.write("Please enter the upper y-level: ")
- local upper = nil
- repeat upper = tonumber(io.read()) until upper ~= nil
- term.clearLine()
- return lower, upper
- end
- local function askForArea()
- term.clearLine()
- term.setCursorPos(1, 5)
- term.write("Please enter the length: ")
- local length = nil
- repeat length = tonumber(io.read()) until length ~= nil
- term.clearLine()
- term.setCursorPos(1, 5)
- term.write("Please enter the width: ")
- local width = nil
- repeat width = tonumber(io.read()) until width ~= nil
- term.clearLine()
- return width, length
- end
- local function main()
- local config_file = nil -- this should be set to a file path if you would like not to have input height or area all the time
- local status = status[1]
- printProgramInfo()
- printStatus(status, nil, nil, nil, nil, nil)
- local lower, upper = askForHeightRange(config_file)
- local width, length = askForArea(config_file)
- mine(status, nil, nil, lower, upper, width, length)
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement