UNOBTANIUM

FurnaceStation Turtle

Jun 11th, 2015
373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.83 KB | None | 0 0
  1.  
  2.  
  3. --[[
  4. FURNACE: SLAVE
  5.  
  6.  
  7.  
  8. incomming tasks:
  9. refuelall
  10. checkitems
  11. retrieveitems
  12. additems (or noemptyfurnace)
  13.  
  14. output tasks:
  15. updatefurnace
  16. getemptyfurnace
  17. idle
  18. error
  19.  
  20. tasks have IDs
  21. slave can drop items of the same kind into the same furnce (comes back if its more then 64 and tells the nexus what he did)
  22. nexus lists all running tasks and furnaces
  23. slave has to check if it is burnable (if there was no output blocks. grab the items out and drop it into the output chest)
  24. check if fuel chest ist full
  25.  
  26.  
  27. inventory management:
  28. slot state: empty, fuel, ore, finished
  29. check if ore is burnable (drop items and try to pick them up again. if they are still the same amount the items cant be smelted)
  30. drop finished items into the output chest
  31. fuel used to refuel furnaces (or turtle?). take a large amount if 'refuelall'!!!!!
  32. empty slots can be used for everything
  33.  
  34. free empty slots
  35. check for the same type of items in different slots
  36. merge stacks?
  37.  
  38. ]]
  39.  
  40.  
  41. local system = "my furnace";
  42. rednet.open("left");
  43. local pos = {["x"]=0, ["y"]=0, ["z"]=0, ["r"]=1};
  44.  
  45. local currentTask = {["taskname"]="idle"};
  46. local slot = {};
  47. for i = 1, 16, 1 do
  48.     table.insert(slot, {["state"]="empty"});
  49. end
  50.  
  51.  
  52. -- MOVEMENT
  53.  
  54. function savePos()
  55.     local file = fs.open("furnacestation","w");
  56.         file.writeLine(string.gsub(textutils.serialize(pos),"\n%S-",""));
  57.         file.writeLine(string.gsub(textutils.serialize(currentTask),"\n%S-",""));
  58.         file.writeLine(string.gsub(textutils.serialize(slot),"\n%S-",""));
  59.         file.writeLine(system);
  60.     file.close();
  61. end
  62.  
  63. function load()
  64.     if not fs.exists("furnacestation") then return end
  65.     local file = fs.open("furnacestation","r")
  66.         pos = textutils.unserialize(file.readLine())
  67.         currentTask = textutils.unserialize(file.readLine())
  68.         slot = textutils.unserialize(file.readLine())
  69.         system = file.readLine();
  70.     file.close();
  71. end
  72.  
  73. function turnLeft()
  74.     if (pos.r == 0) then
  75.         pos.r = 3;
  76.     else
  77.         pos.r = pos.r - 1;
  78.     end
  79.     savePos();
  80.     turtle.turnLeft();
  81. end
  82.  
  83. function turnRight()
  84.     pos.r = (pos.r + 1) % 4;
  85.     savePos();
  86.     turtle.turnRight();
  87. end
  88.  
  89. function rotate(r)
  90.     while (not (pos.r == r)) do
  91.         if (r == pos.r-1 or (r == 3 and pos.r == 0)) then
  92.             turnLeft();
  93.         elseif (r == pos.r+1 or (r == 0 and pos.r == 3)) then
  94.             turnRight();
  95.         elseif math.ceil(math.random()) < 0.5 then
  96.             turnLeft()
  97.         else
  98.             turnRight();
  99.         end
  100.     end
  101. end
  102.  
  103. function forward()
  104.     if (pos.r == 0) then
  105.         pos.y = pos.y + 1;
  106.     elseif (pos.r == 1) then
  107.         pos.x = pos.x + 1;
  108.     elseif (pos.r == 2) then
  109.         pos.y = pos.y - 1;
  110.     elseif (pos.r == 3) then
  111.         pos.x = pos.x - 1;
  112.     end
  113.     savePos();
  114.     turtle.forward();
  115. end
  116.  
  117. function up()
  118.     pos.z = pos.z + 1;
  119.     savePos();
  120.     turtle.up();
  121. end
  122.  
  123. function down()
  124.     pos.z = pos.z - 1;
  125.     savePos();
  126.     turtle.down();
  127. end
  128.  
  129. function moveTo(x,y,z)
  130.     while (not (x == pos.x and y == pos.y and z == pos.z)) do
  131.  
  132.         if (pos.y == 0 and not (z == pos.z) and pos.x > 0) then
  133.             while (z > pos.z) do
  134.                 if (turtle.detectUp()) then
  135.                     moveTo(0, 0, pos.z);
  136.                 end
  137.                 up();
  138.             end
  139.             while (z < pos.z) do
  140.                 if (turtle.detectDown()) then
  141.                     moveTo(0, 0, pos.z);
  142.                 end
  143.                 down();
  144.             end
  145.         elseif (not (pos.y == y) and pos.x > 0) then
  146.             if (pos.y < y) then
  147.                 rotate(0);
  148.                 forward();
  149.             elseif (pos.y > y) then
  150.                 rotate(2);
  151.                 forward();
  152.             end
  153.         elseif (not (pos.x == x)) then
  154.             if (pos.x < x) then
  155.                 rotate(1);
  156.                 forward();
  157.             elseif (pos.x > x) then
  158.                 rotate(3);
  159.                 forward();
  160.             end
  161.         elseif (not (pos.z == z)) then
  162.             if (pos.y == -1) then
  163.                 rotate(0);
  164.                 forward();
  165.             elseif (pos.y == 1) then
  166.                 rotate(2);
  167.                 forward();
  168.             end
  169.         end
  170.     end
  171. end
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178. -- INVENTORY
  179.  
  180. function countSlots(type)
  181.     local count = 0;
  182.     for i = 1, 16, 1 do
  183.         if (slot[i].state == type) then
  184.             count = count + 1;
  185.         end
  186.     end
  187.     return count;
  188. end
  189.  
  190. function findSlots(type)
  191.     local a = {};
  192.     for i = 1, 16, 1 do
  193.         if (slot[i].state == type) then
  194.             table.insert(a, i);
  195.         end
  196.     end
  197.     return a;
  198. end
  199.  
  200.  
  201. -- BASE INTERACTIONS
  202.  
  203. function goToBase(askForTask)
  204.     askForTask = askForTask or true
  205.     if (not (pos.x == 0 and pos.y == 0 and pos.z == 0)) then
  206.         moveTo(1,0,0);
  207.         rotate(3);
  208.         forward();
  209.         rotate(1);
  210.     end
  211.     dropAllItems();
  212.     checkFuelReserves();
  213.     refuelTurtle();
  214.     if (askForTask) then
  215.         takeItemsOut();
  216.     end
  217. end
  218.  
  219. function dropAllItems()
  220.     dropItems("finished", "front", "The output chest is full! Please take items out!");
  221.     dropItems("ores", "top", "The input chest is too full! Please take some items out!");
  222.     if (countSlots("fuel") ~= 2) then
  223.         dropItems("fuel", "down", "The fuel chest is too full! Please take some items out!");
  224.     end
  225. end
  226.  
  227. function dropItems(type, direction, error)
  228.     if (countSlots(type) == 0) then
  229.         return;
  230.     end
  231.     if (type == "finished") then
  232.         rotate(2);
  233.     end
  234.     slots = findSlots(type);
  235.     for i, s in pairs(slots) do
  236.         if (turtle.getItemCount(s) > 0) then
  237.             turtle.select(s);
  238.             local b = drop(direction);
  239.             if (not b or (b and turtle.getItemCount(s) > 0)) then
  240.                 for i = 1, 10, 1 do
  241.                     drop(direction);
  242.                 end
  243.                 if (turtle.getItemCount(s) > 0) then
  244.                     sendMessage({["state"]="error", ["errormessage"]=error});
  245.                     if (not (type == "finished")) then
  246.                         return;
  247.                     end
  248.                     while (turtle.getItemCount(s) > 0) do
  249.                         os.sleep(15);
  250.                         drop(direction);
  251.                     end
  252.                 end
  253.             end
  254.         end
  255.         slot[s].state = "empty";
  256.         savePos();
  257.     end
  258.     if (type == "finished") then
  259.         rotate(1);
  260.     end
  261. end
  262.  
  263. function drop(direction)
  264.     if (direction == "front") then
  265.         return turtle.drop();
  266.     elseif (direction == "down") then
  267.         return turtle.dropDown();
  268.     elseif (direction == "up") then
  269.         return turtle.dropUp();
  270.     end
  271. end
  272.  
  273. function takeItemsOut()
  274.     local emptySlots = findSlots("empty");
  275.     for i, s in pairs(emptySlots) do
  276.         turtle.select(s)
  277.         turtle.suckUp();
  278.         if (turtle.getItemCount(s) == 0) then
  279.             break;
  280.         else
  281.             slot[s].state = "ore";
  282.             savePos();
  283.             break;
  284.         end
  285.     end
  286.     if (countSlots("ore") == 0) then
  287.         local delay = os.startTimer(10);
  288.         while (true) do
  289.             local event = { os.pullEvent() };
  290.             if (event[1] == "timer" and event[2] == delay) then
  291.                 break;
  292.             elseif (event[1] == "redstone") then
  293.                 break;
  294.             end
  295.         end
  296.         sendMessage({["state"]="idle"});
  297.     else
  298.         sendMessage({["state"]="getemptyfurnace"});
  299.     end
  300. end
  301.  
  302. function refuelTurtle()
  303.     if (turtle.getFuelLevel() < 300) then
  304.         while (true) do
  305.             local fuelSlots = findSlots("fuel");
  306.             if (table.getn(fuelSlots) == 0) then
  307.                 takeFuelOut(1);
  308.                 fuelSlots = findSlots("fuel");
  309.             end
  310.             for i, s in pairs(fuelSlots) do
  311.                 turtle.select(s);
  312.                 while (turtle.getItemCount(s) > 0) do
  313.                     turtle.refuel(1);
  314.                     if (turtle.getFuelLevel() > 2000) then
  315.                         return;
  316.                     end
  317.                 end
  318.             end
  319.         end
  320.     end
  321. end
  322.  
  323. function takeFuelOut(stacks)
  324.     stacks = stacks or 1
  325.     if (stacks > 16) then
  326.         stacks = 16;
  327.     end
  328.     while (true) do
  329.         local emptySlots = findSlots("empty");
  330.         for i = 1, stacks, 1 do
  331.             if (emptySlots[i] == null) then
  332.                 break;
  333.             end
  334.             turtle.select(emptySlots[i]);
  335.             turtle.suckDown();
  336.             if (turtle.getItemCount(emptySlots[i]) > 0) then
  337.                 slot[emptySlots[i]].state = "fuel";
  338.                 savePos();
  339.             end
  340.         end
  341.         local fuelSlots = findSlots("fuel");
  342.         if (table.getn(fuelSlots) == 0) then
  343.             sendMessage({["state"]="error", ["errormessage"]="No fuel left! Please put fuel into the chest!"});
  344.             os.sleep(60);
  345.         else
  346.             return;
  347.         end
  348.     end
  349. end
  350.  
  351. function checkFuelReserves()
  352.     while (true) do
  353.         if (countSlots("fuel") == 2) then
  354.             return;
  355.         end
  356.         dropItems("fuel", "down", "The fuel chest is too full! Please take some items out!");
  357.         takeFuelOut(2);
  358.         if (countSlots("fuel") < 2) then
  359.             local fuelSlots = findSlots("fuel");
  360.             local amount = 0;
  361.             for i, s in pairs(fuelSlots) do
  362.                 amount = turtle.getItemCount(s);
  363.             end
  364.             if (amount >= 128) then
  365.                 return;
  366.             elseif (amount < 32) then
  367.                 sendMessage({["state"]="error", ["errormessage"]="Not enough fuel left! Please put fuel into the chest!"});
  368.                 return;
  369.             else
  370.                 sendMessage({["state"]="error", ["errormessage"]="Low on fuel! Please put fuel into the chest!"});
  371.                 return;
  372.             end
  373.         else
  374.             return;
  375.         end
  376.     end
  377. end
  378.  
  379.  
  380. -- FURNACE INTERACTIONS
  381.  
  382.  
  383. function doTask()
  384.     while (true) do
  385.         term.clear();
  386.         term.setCursorPos(1, 1);
  387.         print(textutils.serialize(pos));
  388.         print(textutils.serialize(currentTask));
  389.  
  390.         if (currentTask.taskname == "refuelall") then
  391.             refuelAll();
  392.         elseif (currentTask.taskname == "refuel") then
  393.             refuelFurnace();
  394.         elseif (currentTask.taskname == "retrieveitems") then
  395.             retrieveItem();
  396.         elseif (currentTask.taskname == "additems") then
  397.             addOres();
  398.         elseif (currentTask.taskname == "getemptyfurnace") then
  399.             sendMessage({["state"]="getemptyfurnace"});
  400.             waitForInput();
  401.         elseif (currentTask.taskname == "idle") then
  402.             sendMessage({["state"]="idle"});
  403.             waitForInput();
  404.         end
  405.     end
  406. end
  407.  
  408. function finishedTask()
  409.     if (countSlots("ore") == 0) then
  410.         currentTask = {["taskname"]="idle"};
  411.     else
  412.         currentTask = {["taskname"]="getemptyfurnace"};
  413.     end
  414.     savePos();
  415. end
  416.  
  417.  
  418. function refuelAll()
  419.     -- TODO
  420.     finishedTask();
  421. end
  422.  
  423. function refuelFurnace()
  424.     local fuelSlotsCount = countSlots("fuel");
  425.     if (fuelSlotsCount == 0) then
  426.         goToBase(false);
  427.     end
  428.  
  429.     moveTo(currentTask.x, 0, 0);
  430.     if (currentTask.y == 1) then
  431.         rotate(0);
  432.     else
  433.         rotate(2);
  434.     end
  435.     local fuelSlots = findSlots("fuel");
  436.     for i, s in pairs(fuelSlots) do
  437.         local count = turtle.getItemCount(s);
  438.         turtle.select(s);
  439.         turtle.drop();
  440.         sendMessage({["state"]="updatefurnace", ["action"]="addedFuel", ["furnacenumber"]=currentTask.furnacenumber, ["itemvalue"]=count;});
  441.         if (turtle.getItemCount(s) > 0) then
  442.             break;
  443.         else
  444.             slot[s].state = "empty";
  445.             savePos();
  446.         end
  447.     end
  448.     finishedTask();
  449. end
  450.  
  451. function retrieveItem()
  452.     if (countSlots("empty") == 0) then
  453.         if (countSlots("fuel") + countSlots("finished") == 16) then
  454.             goToBase(false);
  455.         else
  456.             local tempTask = currentTask;
  457.             addOres();
  458.             currentTask = tempTask;
  459.         end
  460.     end
  461.     moveTo(currentTask.x, currentTask.y, -1);
  462.     local emptySlots = findSlots("empty");
  463.     s = emptySlots[1];
  464.     turtle.select(s);
  465.     turtle.suckUp();
  466.     if (turtle.getItemCount(s) == currentTask.itemcount) then
  467.         slot[s].state = "finished";
  468.     elseif (turtle.getItemCount(s) == 0) then
  469.         moveTo(currentTask.x, currentTask.y, 1);
  470.         slot[s].state = "finished";
  471.         turtle.suckDown();
  472.     else
  473.         slot[s].state = "finished";
  474.         while (turtle.getItemCount(s) ~= currentTask.itemcount) do
  475.             os.sleep(10);
  476.             turtle.suckUp();
  477.         end
  478.     end
  479.     sendMessage({["state"]="updatefurnace", ["action"]="retrievedItems", ["furnacenumber"]=currentTask.furnacenumber, ["itemvalue"]=turtle.getItemCount(s)});
  480.     savePos();
  481.     finishedTask();
  482. end
  483.  
  484. function addOres() -- can be improved for fuel efficiency
  485.     moveTo(currentTask.x, currentTask.y, 1);
  486.     local oreSlots = findSlots("ore");
  487.     local s = oreSlots[1];
  488.     local count = turtle.getItemCount(s);
  489.     turtle.select(s);
  490.     turtle.dropDown();
  491.     if (turtle.getItemCount(s) == 0) then
  492.         slot[s].state = "empty";
  493.         sendMessage({["state"]="updatefurnace", ["action"]="addedItems", ["furnacenumber"]=currentTask.furnacenumber, ["itemvalue"]=count});
  494.     elseif (count-turtle.getItemCount(s) == 0) then
  495.         slot[s].state = "finished";
  496.     else
  497.         sendMessage({["state"]="updatefurnace", ["action"]="addedItems", ["furnacenumber"]=currentTask.furnacenumber, ["itemvalue"]=(count-turtle.getItemCount(s))});
  498.     end
  499.     savePos();
  500.     finishedTask();
  501. end
  502.  
  503.  
  504. -- MESSAGES
  505.  
  506. function sendMessage(message)
  507.     rednet.broadcast(textutils.serialize(message), system);
  508. end
  509.  
  510.  
  511. function waitForInput()
  512.     while (true) do
  513.         local e = { os.pullEvent() }
  514.         if (e[1] == "rednet_message" and e[4] == system) then
  515.             message = textutils.unserialize(e[3]);
  516.             if (type(message) == "table") then
  517.                 if (message["taskname"] == "refuel" or message["taskname"] == "retrieveitems" or message["taskname"] == "additems" or message["taskname"] == "refuelall") then
  518.                     currentTask = message;
  519.                     return; -- to doTask()
  520.                 elseif (message["taskname"] == "checkitems") then
  521.                     currentTask = {["taskname"]="idle"};
  522.                     goToBase(); -- may break stuff when ore items got picked up allready? -- sends message, requires response
  523.                 elseif (message["taskname"] == "noemptyfurnace") then
  524.                     currentTask = {["taskname"]="idle"};
  525.                     os.sleep(15);
  526.                     takeItemsOut(); -- sends message, requires response
  527.                 end
  528.             end
  529.         end
  530.     end
  531. end
  532.  
  533. load();
  534. doTask();
Advertisement
Add Comment
Please, Sign In to add comment