Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Computercraft Turtle-Quarry-Program
- -- By Marius Graefe
- -- default values:
- local width = 16;
- local height = 16;
- local depth = 16;
- local noCobble = false;
- --------------------------
- -- DO NOT EDIT BELOW
- --------------------------
- local chestPos = {x = 0, y = 0, z = 0};
- local moveHistory = {};
- local Move = {
- ["Up"] = 0;
- ["Forward"] = 1;
- ["Down"] = 2;
- ["Backward"] = 3;
- ["TurnRight"] = 4;
- ["TurnLeft"] = 5;
- };
- -- copy a table by value
- function table.copy(t)
- local t2 = {};
- for k,v in pairs(t) do
- t2[k] = v;
- end
- return t2;
- end
- -- terminate the program
- function quit(msg)
- if msg ~= nil then
- print(msg);
- end
- os.exit();
- end
- -- call mommy
- function callForHelp(msg)
- print( "Help me I'm stuck here. Please free me and type \"continue\". To terminate the program type \"stop\" or \"exit\". To refuel the turtle type \"refuel <n>\"" );
- if msg ~= nil then
- print("Error Message was:\n" .. msg);
- end
- local ok = false;
- while not ok do
- input = io.read();
- r = input:match("refuel (%d+)");
- if input == "continue" then
- if turtle.getFuelLevel() <= 0 then
- print("Error: no fuel, put some fuel-items into the inventory and type \"refuel <n>\"");
- else
- ok = true;
- end
- elseif input == "stop" or input == "exit" then
- quit();
- elseif r ~= nil then
- turtle.refuel(tonumber(r));
- print("Fuel level is now " .. turtle.getFuelLevel());
- else
- print("Unknown Command.");
- end
- end
- end
- -- rotate a vector with 3 components to the right/left
- function rotateVector(vec, direction)
- local res = {z = vec.z};
- if direction == Move.TurnLeft then
- res.x = -vec.y;
- res.y = vec.x;
- elseif direction == Move.TurnRight then
- res.x = vec.y;
- res.y = -vec.x;
- else
- error("rotateVector: no turn direction: " .. direction);
- end
- return res;
- end
- -- move vector by offset
- function moveVector(vec, offset)
- local res = {};
- res.x = vec.x + offset.x;
- res.y = vec.y + offset.y;
- res.z = vec.z + offset.z;
- return res;
- end
- -- throw all items that are equal to the first inventory slot out
- function clearInventory()
- turtle.select(1);
- for i = 2, 16 do
- if turtle.compareTo(i) then
- turtle.select(i);
- turtle.dropDown();
- turtle.select(1);
- end
- end
- end
- -- dig forward, does NOT guarrantee that there is no block in front afterwards
- function digAll(bForce)
- if bForce ~= nil and bForce == true then
- turtle.dig();
- end
- while turtle.detect() do turtle.dig(); end
- end
- -- dig up, does NOT guarrantee that there is no block upwards afterwards
- function digUpAll(bForce)
- if bForce ~= nil and bForce == true then
- turtle.digUp();
- end
- while turtle.detectUp() do turtle.digUp(); end
- end
- -- dig down, does NOT guarrantee that there is no block downwards afterwards
- function digDownAll(bForce)
- if bForce ~= nil and bForce == true then
- turtle.digDown();
- end
- while turtle.detectDown() do turtle.digDown(); end
- end
- -- call digUpAll() / digAll() / digDownAll() for direction equal to 1/2/3
- function digDir(direction, bForce)
- if direction == Move.Up then
- digUpAll(bForce);
- elseif direction == Move.Forward then
- digAll(bForce);
- elseif direction == Move.Down then
- digDownAll(bForce);
- elseif direction == Move.Backward then
- turnLeft();
- turnLeft();
- digAll(bForce);
- turnRight();
- turnRight();
- else
- error("digDir: no such direction: " .. direction);
- end
- end
- -- call attack functions
- function attackDir(direction)
- for i = 1, 10 do
- if direction == Move.Up then
- turtle.attackUp();
- elseif direction == Move.Forward then
- turtle.attack();
- elseif direction == Move.Down then
- turtle.attachDown();
- elseif direction == Move.Backward then
- turnLeft();
- turnLeft();
- turtle.attack();
- turnRight();
- turnRight();
- else
- error("attackDir: no such direction: " .. direction);
- end
- end
- end
- -- add to history
- function addHistory(move)
- table.insert(moveHistory, move);
- end
- -- get the appropriate turtle function
- function getMoveFunction(direction)
- local moveFunction = nil;
- if direction == Move.Up then
- moveFunction = turtle.up;
- elseif direction == Move.Forward then
- moveFunction = turtle.forward;
- elseif direction == Move.Down then
- moveFunction = turtle.down;
- elseif direction == Move.Backward then
- moveFunction = turtle.back;
- else
- error("getMoveFunction: No such direction: " .. direction);
- end
- return moveFunction;
- end
- -- move the chest position locally
- function moveChestPos(direction)
- if direction == Move.Up then
- chestPos = moveVector(chestPos, {x = 0, y = 0, z = -1});
- elseif direction == Move.Down then
- chestPos = moveVector(chestPos, {x = 0, y = 0, z = 1});
- elseif direction == Move.Forward then
- chestPos = moveVector(chestPos, {x = -1, y = 0, z = 0});
- elseif direction == Move.Backward then
- chestPos = moveVector(chestPos, {x = 1, y = 0, z = 0});
- elseif direction == Move.TurnRight then
- chestPos = rotateVector(chestPos, Move.TurnLeft);
- elseif direction == Move.TurnLeft then
- chestPos = rotateVector(chestPos, Move.TurnRight);
- else
- error("Unknown moveChest command: " .. direction);
- end
- -- print("chestPos is " .. chestPos.x .. " " .. chestPos.y .. " " .. chestPos.z .. ".");
- end
- -- move the turtle and update history
- function move(direction, dist)
- local dist = dist or 1;
- local moveFunction = getMoveFunction(direction);
- for i = 1, dist do
- local digCount = 0;
- while not moveFunction() do
- digCount = digCount + 1;
- digDir(direction, i > 10);
- if digCount%10 == 0 then
- attackDir(direction);
- end
- if digCount > 256 then
- callForHelp("Cannot move anymore...");
- end
- end
- addHistory(direction);
- moveChestPos(direction);
- end
- end
- -- move the turtle up (guaranteed) and update history
- function up(dist)
- move(Move.Up, dist);
- end
- -- move the turtle down (guaranteed) and update history
- function down(dist)
- move(Move.Down, dist);
- end
- -- move the turtle forward (guaranteed) and update history
- function forward(dist)
- move(Move.Forward, dist);
- end
- -- move the turtle forward (guaranteed) and update history
- function backward(dist)
- move(Move.Backward, dist);
- end
- -- get the appropriate turtle function
- function getTurnFunction(direction)
- if direction == Move.TurnRight then
- return turtle.turnRight;
- elseif direction == Move.TurnLeft then
- return turtle.turnLeft;
- else
- error("No such turning direction: " .. direction);
- return nil;
- end
- end
- -- turn and update history
- function turn(direction)
- local turnFunction = getTurnFunction(direction);
- turnFunction();
- addHistory(direction);
- moveChestPos(direction);
- end
- -- turn left and update history
- function turnLeft()
- turn(Move.TurnLeft);
- end
- -- turn right and update history
- function turnRight()
- turn(Move.TurnRight);
- end
- -- dig the three blocks up/front/down and move forward
- function dig3()
- digUpAll();
- digAll();
- digDownAll();
- forward();
- end
- -- is the inventory full?
- function isInventoryFull()
- for i = 1, 16 do
- if turtle.getItemCount(i) == 0 then
- return false;
- end
- end
- return true;
- end
- -- 180 degree turn, does not move if bNoMove is true
- function turn180(direction, bNoMove)
- turn(direction);
- if not bNoMove then
- dig3();
- end
- turn(direction);
- end
- -- move to position in local coordinates
- function moveToPos(vec)
- -- move along z
- if vec.z > 0 then
- up(vec.z);
- else
- down(-vec.z);
- end
- -- move along x
- if vec.x < 0 then
- turnLeft();
- turnLeft();
- end
- forward(math.abs(vec.x));
- if vec.x < 0 then
- turnLeft();
- turnLeft();
- end
- -- move along y
- if vec.y < 0 then
- turnRight();
- else
- turnLeft();
- end
- forward(math.abs(vec.y));
- end
- -- vomit inventory upwards
- function vomitInventory()
- local start = noCobble and 2 or 1;
- for i = start, 16 do
- if turtle.getItemCount(i) > 0 then
- turtle.select(i);
- if not turtle.dropUp() then
- callForHelp("Chest is full");
- end
- end
- end
- turtle.select(1);
- end
- -- move along history
- function moveHistoryBackwards(history)
- for i = #history, 1, -1 do
- if history[i] == Move.Up then
- down();
- elseif history[i] == Move.Down then
- up();
- elseif history[i] == Move.Forward then
- backward();
- elseif history[i] == Move.Backward then
- forward();
- elseif history[i] == Move.TurnRight then
- turnLeft();
- elseif history[i] == Move.TurnLeft then
- turnRight();
- else
- error("Unknown history command: " .. history[i]);
- end
- end
- end
- -- move to chest, unload inventory and return to quarry
- function unload(bNoReturnToQuarry)
- print("Inventory Full, moving to chest");
- moveHistory = {}; -- reset move history
- local oldChestPos = table.copy(chestPos);
- moveToPos(oldChestPos);
- vomitInventory();
- if bNoReturnToQuarry == nil or bNoReturnToQuarry == false then
- print("Moving back to quarry");
- local oldHistory = table.copy(moveHistory);
- moveHistoryBackwards(oldHistory);
- end
- end
- function getFuelForUnload()
- return math.abs(chestPos.x) + math.abs(chestPos.y) + math.abs(chestPos.z) + 1;
- end
- function mainProg(x, y, z)
- print("starting quarry size " .. x .. " " .. y .. " " .. z .. ".");
- local lastTurnLeft = true;
- cobbleCounter = 0;
- for i = 1, z/3 do
- down((i==1) and 2 or 3);
- for j = 1, y do
- for k = 1, x do
- if isInventoryFull() then
- unload();
- end
- dig3();
- cobbleCounter = cobbleCounter + 3;
- if noCobble and cobbleCounter >= 45 then
- clearInventory();
- cobbleCounter = 0;
- end
- if turtle.getFuelLevel() <= getFuelForUnload() then
- unload(true);
- callForHelp("No more fuel.");
- end
- end
- turn180(lastTurnLeft and Move.TurnRight or Move.TurnLeft, j == n);
- lastTurnLeft = not lastTurnLeft;
- end
- lastTurnLeft = not lastTurnLeft;
- end
- digUpAll();
- digDownAll();
- unload(true);
- end
- function startProgram()
- print("Program by Marius Graefe");
- print("Type help for help\n");
- while true do
- input = io.read();
- local w = input:match("width (%d+)");
- local h = input:match("height (%d+)");
- local d = input:match("depth (%d+)");
- local c = input:match("nocobble (%a+)");
- local r = input:match("refuel (%d+)");
- if input == "help" then
- displayHelp();
- elseif input == "status" then
- displayStatus();
- elseif w ~= nil then
- width = tonumber(w);
- print("width is now " .. width);
- elseif h ~= nil then
- height = tonumber(h);
- print("height is now " .. height);
- elseif d ~= nil then
- depth = d;
- print("depth is now " .. depth);
- elseif r ~= nil then
- turtle.refuel(tonumber(r));
- print("Fuel level is now " .. turtle.getFuelLevel());
- elseif input == "start" then
- if turtle.getFuelLevel() <= 0 then
- print("Error: no fuel, put some fuel-items into the inventory and type \"refuel <n>\"");
- else
- mainProg(width, height, depth);
- end
- elseif input == "stop" or input == "exit" then
- quit();
- elseif c ~= nil and (c == "on" or c == "off") then
- noCobble = c == "on";
- print(noCobble and "No-Cobble-Mode ON" or "No-Cobble-Mode OFF");
- else
- print("unknown command, type help for help");
- end
- end
- end
- function displayStatus()
- print("Quarry width: " .. width);
- print("Quarry height: " .. height);
- print("Quarry depth: " .. depth);
- print("No Cobble Mode " .. (noCobble and "ON" or "OFF"));
- end
- function pressEnter()
- io.write("[Enter]");
- io.read();
- end
- function displayHelp()
- print("Commands:");
- print(" status\ndisplay status");
- print(" start\nstarts digging");
- print(" stop/exit\nterminates program");
- print(" refuel <n>\nrefuel the turtle");
- pressEnter();
- print(" width <number>\nspecify width of quarry, i. e. how much the turtle digs forward");
- print(" height <number>\nspecify height of quarry, i.e. how much the turtle digs right");
- print(" depth <number>\nspecify depth of quarry, i.e. how much the turtle digs downwards");
- pressEnter();
- print(" nocobble on/off\nspecify if the turtle should not gather items equal to the item in the first slot");
- end
- startProgram();
Advertisement
Add Comment
Please, Sign In to add comment