computercraft/turtles/mine.lua

352 lines
8.1 KiB
Lua

-- Short URL to raw: https://tiny.tobast.fr/cc_mineturtle
facing = 0 -- Direction towards mining shafts. Incr. clockwise.
height = 0 -- At ground level, lowest mining level
MAX_HEIGHT = 7 -- Will not mine higher than this.
depth = -2 -- Out of the mining shafts
side = 6 -- Increases towards the right when facing shafts
DOCK_POINT_H = 0
DOCK_POINT_D = -2
DOCK_POINT_S = 6
DROP_POINT_H = 0
DROP_POINT_D = -2
DROP_POINT_S = 0
FUEL_POINT_H = 0
FUEL_POINT_D = -2
FUEL_POINT_S = 3
FUEL_EXPECTATION = 2000
FUEL_LOW = 1000
SHAFT_DEPTH = 100
-- Start at this position to find the next shaft
next_shaft_side = 0
next_shaft_height = 0
function distance_to_drop()
return math.abs(depth - DROP_POINT_D)
+ math.abs(height - DROP_POINT_H)
+ math.abs(side - DROP_POINT_S);
end
function distance_to_refuel()
local drop_to_fuel = math.abs(FUEL_POINT_D - DROP_POINT_D)
+ math.abs(FUEL_POINT_H - DROP_POINT_H)
+ math.abs(FUEL_POINT_S - DROP_POINT_S);
return distance_to_drop() + drop_to_fuel;
end
function turn_abs(dir)
local diff = (dir - facing) % 4
if diff == 3 then
turtle.turnLeft()
else
for i=1,diff do turtle.turnRight() end
end
facing = dir
end
function turn_rel(dir)
turn_abs((facing + dir) % 4)
end
-- Dumps the current turtle position
function _dump_pos()
print("Current position: H "..height.." S "..side.." D "..depth)
end
-- Updates the turtle position for a move in the given direction
function _count_move_dir(dir)
dir = dir % 4
if dir == 0 then depth = depth + 1
elseif dir == 1 then side = side + 1
elseif dir == 2 then depth = depth - 1
elseif dir == 3 then side = side - 1
end
end
function move_forward(will_retry)
rc, desc = turtle.forward()
if not rc then
if will_retry then
return false
else
abort("Move: "..desc)
end
end
_count_move_dir(facing)
return true
end
function move_back()
rc, desc = turtle.back()
if not rc then abort("Move: "..desc) end
_count_move_dir(facing + 2)
end
function move_up()
rc, desc = turtle.up()
if not rc then abort("Move: "..desc) end
height = height + 1
end
function move_down()
rc, desc = turtle.down()
if not rc then abort("Move: "..desc) end
height = height - 1
end
function tryhard_forward()
for i=1,5 do
while turtle.detect() do
turtle.dig()
end
if move_forward(true) then
return true
else
sleep(1)
end
end
abort('Giving up trying to move forward.')
end
function go_to_depth(dd)
turn_abs(0)
while depth > dd do
move_back()
end
while depth < dd do
move_forward()
end
end
-- Go to a target position, assuming no excavation is needed
function go_to(dh, dd, ds)
go_to_depth(0)
if height ~= dh then
while height > dh do
move_down()
end
while height < dh do
move_up()
end
end
if side ~= ds then
turn_abs(1)
while side > ds do
move_back()
end
while side < ds do
move_forward()
end
end
go_to_depth(dd)
end
-- enter failed/done state
function abort(msg)
print("ABORTING: ")
print(msg)
go_to(DOCK_POINT_H, DOCK_POINT_D, DOCK_POINT_S)
making_a_fatal_error_awdadwdaw()
end
-- Discharge the inventory in the drop chest
function discharge_inventory()
go_to(DROP_POINT_H, DROP_POINT_D, DROP_POINT_S)
for slot=1,16 do
turtle.select(slot)
turtle.dropUp()
end
end
-- Refuel from fuel point
function refuel_turtle()
turtle.select(1)
if turtle.getItemCount() > 0 then
return false
end
go_to(FUEL_POINT_H, FUEL_POINT_D, FUEL_POINT_S)
while turtle.getFuelLevel() < FUEL_EXPECTATION do
local rc, desc = turtle.suckUp()
if not rc then
abort("No more fuel available")
end
local rc, desc = turtle.refuel()
if not rc then
abort("Found some non-fuel in the fuel")
end
end
end
-- Find the next unmined shaft and end up in front of it
function find_next_shaft()
function is_shaft_pos()
if side % 2 == 1 then
return false
elseif side % 4 == 0 then
return height % 3 == 0
elseif side % 4 == 2 then
return height % 3 ~= 0
end
end
function is_shaft()
return is_shaft_pos() and turtle.detect()
end
go_to(next_shaft_height, 0, next_shaft_side)
while true do
if side % 2 == 0 then
while height < MAX_HEIGHT - 1 do
if is_shaft() then
return
end
if turtle.detectUp() then
turtle.digUp()
end
move_up()
end
if is_shaft() then
return
end
else
while height > 0 do
if is_shaft() then
return
end
if turtle.detectDown() then
turtle.digDown()
end
move_down()
end
if is_shaft() then
return
end
end
turn_abs(1)
if turtle.detect() then
turtle.dig()
end
move_forward()
turn_abs(0)
end
end
function is_block_precious(block)
local WORTHY_BLOCKS = {
{ name = 'minecraft:coal_ore' },
{ name = 'minecraft:iron_ore' },
{ name = 'minecraft:gold_ore' },
{ name = 'minecraft:lapis_ore' },
{ name = 'minecraft:redstone_ore' },
{ name = 'minecraft:diamond_ore' },
{ name = 'minecraft:emerald_ore' },
{ name = 'ic2:resource', state_type = 'lead_ore' },
{ name = 'ic2:resource', state_type = 'copper_ore' },
{ name = 'ic2:resource', state_type = 'tin_ore' },
{ name = 'ic2:resource', state_type = 'uranium_ore' },
}
if block then
for id, refblock in ipairs(WORTHY_BLOCKS) do
if block.name == refblock.name then
if refblock.state_type then
if (block.state and block.state.type
and block.state.type == refblock.state_type) then
return true
end
else
return true
end
end
end
end
return false
end
-- Mine worthy blocks around the current turtle position
function mine_around()
exists, details = turtle.inspectUp()
if exists and is_block_precious(details) then
turtle.digUp()
end
exists, details = turtle.inspectDown()
if exists and is_block_precious(details) then
turtle.digDown()
end
for lookat=1,3,2 do -- lookat in {1,3}
turn_abs(lookat)
exists, details = turtle.inspect()
if exists and is_block_precious(details) then
turtle.dig()
end
end
turn_abs(0)
end
-- Mine a new shaft in front of the turtle
function mine_shaft()
turn_abs(0)
while depth < SHAFT_DEPTH do
while turtle.detect() do
turtle.dig()
end
tryhard_forward()
if depth > 1 then -- if not we confuse find_next_shaft
mine_around()
end
end
turn_abs(2)
while depth > 0 do
while turtle.detect() do
turtle.dig()
end
move_forward()
end
turn_abs(0)
end
-- Main function
function main()
if turtle.getFuelLevel() < distance_to_refuel() then
print("Not enough fuel to begin with.")
return
elseif turtle.getFuelLevel() < FUEL_LOW then
refuel_turtle()
end
while true do
print("Finding shaft")
find_next_shaft()
next_shaft_height = height
next_shaft_side = side
print("Mining shaft at position:")
_dump_pos()
mine_shaft()
print("Discharging")
discharge_inventory()
if turtle.getFuelLevel() < FUEL_LOW then
refuel_turtle()
end
end
end
main()