Advertisement
NTins

Totoro Recrusive Miner 0.5h (Unofficial)

Jun 17th, 2015
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.85 KB | None | 0 0
  1. -- Totoro Recursive Miner  0.5H --
  2. -- computercraft.ru (c) 01.2015 --
  3. local robot = require('robot')
  4. local event = require('event')
  5. local sides = require('sides')
  6. local computer = require('computer')
  7. local com = require('component')
  8.  
  9. function trytoload(name)
  10.   if com.isAvailable(name) then
  11.     return com.getPrimary(name)
  12.   else
  13.     return nil
  14.   end
  15. end
  16.  
  17. local gen = trytoload("generator")
  18. local cloader = trytoload("chunkloader")
  19. local control = trytoload("inventory_controller")
  20.  
  21. TECH_SLOTS = 6
  22. VANILLA_CHEST = true
  23. PATHWAYS = true
  24. DROP_TRASH = false
  25. DEAD_END = 30
  26. USE_CLOADER = true
  27.  
  28. INV_SIZE = robot.inventorySize()
  29. if VANILLA_CHEST then INV_SIZE = math.min(INV_SIZE, TECH_SLOTS + 27) end
  30. MAX = 1024
  31.  
  32. -- statictics
  33. local moves = 0
  34.  
  35. local light_allowed = (robot.setLightColor ~= nil)
  36. local color = {}
  37. color.working = 0x00ff00
  38. color.idle = 0xff0000
  39. color.warning = 0xffff10
  40.  
  41. local trash_slots = TECH_SLOTS - 2
  42. local chest_slot = TECH_SLOTS
  43. local empty_slot = TECH_SLOTS + 2
  44. local pchest_slot = TECH_SLOTS - 1
  45.  
  46. local loc = {x=0, y=0, z=0, d=0}
  47. local lode = {}
  48.  
  49. local a = {...}
  50. local l = tonumber(a[1]) or 22
  51. local w = tonumber(a[2]) or 17
  52. local comeback = a[3] or 'false'
  53. local halfw = math.floor(w/2)
  54.  
  55. if a[1] == '?' or a[1] == '-h' or a[1] == '--help' then
  56.   print("Синтаксис: mine <length> [width] [comeback]")
  57.   return
  58. end
  59. if gen == nil then
  60.   print([[[WARNING] Генератор не обнаружен!\n
  61.     Робот не проработает долго без подзарядки.]])
  62. end
  63. if cloader ~= nil then
  64.   print([[[WARNING] Обнаружен чанклодер!\n
  65.     На сервере ComputerCraft IT 1.7.10 его использование
  66.     приведет к моментальной разрядке батареи!]])
  67. end
  68.  
  69. -- ============================= N A V I G A T I O N ============================= --
  70. function forward()
  71.   if robot.forward() then
  72.     if loc.d == 0 then loc.y = loc.y+1
  73.     elseif loc.d == 1 then loc.x = loc.x+1
  74.     elseif loc.d == 2 then loc.y = loc.y-1
  75.     else loc.x = loc.x-1 end
  76.     moves = moves + 1
  77.     return true
  78.   else
  79.     return false
  80.   end
  81. end
  82. function back()
  83.   if robot.back() then
  84.     if loc.d == 0 then loc.y = loc.y-1
  85.     elseif loc.d == 1 then loc.x = loc.x-1
  86.     elseif loc.d == 2 then loc.y = loc.y+1
  87.     else loc.x = loc.x+1 end
  88.     moves = moves + 1
  89.     return true
  90.   else
  91.     return false
  92.   end
  93. end
  94. function up()
  95.   if robot.up() then
  96.     loc.z = loc.z+1
  97.     moves = moves + 1
  98.     return true
  99.   else
  100.     return false
  101.   end
  102. end
  103. function down()
  104.   if robot.down() then
  105.     loc.z = loc.z-1
  106.     moves = moves + 1
  107.     return true
  108.   else
  109.     return false
  110.   end
  111. end
  112. function turnRight()
  113.   loc.d = (loc.d+1)%4
  114.   robot.turnRight()
  115. end
  116. function turnAround()
  117.   loc.d = (loc.d+2)%4
  118.   robot.turnAround()
  119. end
  120. function turnLeft()
  121.   loc.d = (loc.d+3)%4
  122.   robot.turnLeft()
  123. end
  124.  
  125. -- ========================== F U E L  C O N T R O L ============================= --
  126. function check_fuel()
  127.   if gen ~= nil then
  128.     if (computer.maxEnergy() - computer.energy()) > 1000 then
  129.       if gen.count() == 0 then
  130.         for i=empty_slot, INV_SIZE do
  131.           robot.select(i)
  132.           if gen.insert() then break end
  133.         end
  134.       end
  135.     end
  136.   end
  137. end
  138.  
  139. -- ========================== I T E M  C O N T R O L ============================= --
  140. function check_loot()
  141.   for i=empty_slot, INV_SIZE do
  142.     if robot.count(i) == 0 then return false end
  143.   end
  144.   return true
  145. end
  146.  
  147. function check_tool()
  148.     if robot.durability() < 0.2 then
  149.         placePickChest()
  150.         robot.select(pchest_slot)
  151.         robot.suck()
  152.         control.equip()
  153.         robot.drop()
  154.         grabPickChest()
  155.     end
  156. end
  157. function placeChest()
  158.   -- place for chest
  159.   robot.select(chest_slot)
  160.   while robot.swing() do end
  161.   robot.swingUp()
  162.   up()
  163.   while robot.swing() do end
  164.   down()
  165.   robot.place()
  166. end
  167. function placePickChest()
  168.   -- place for chest
  169.   robot.select(pchest_slot)
  170.   while robot.swing() do end
  171.   robot.swingUp()
  172.   up()
  173.   while robot.swing() do end
  174.   down()
  175.   robot.place()
  176. end
  177.  
  178. function grabPickChest()
  179.     -- grab ender chest
  180.     if not VANILLA_CHEST then
  181.         robot.select(pchest_slot)
  182.         robot.swing()
  183.     end
  184. end
  185.  
  186. function unload()
  187.     -- put items
  188.     for i=empty_slot, INV_SIZE do
  189.         robot.select(i)
  190.         while robot.drop() do end
  191.     end
  192. end
  193. function grabChest()
  194.     -- grab ender chest
  195.     if not VANILLA_CHEST then
  196.         robot.select(chest_slot)
  197.         robot.swing()
  198.     end
  199. end
  200.  
  201. function check_trash()
  202.   for i=1, trash_slots do
  203.     -- if too many trash of this type
  204.     if robot.space(i) == 0 then
  205.       -- drop all but one in trash slot
  206.       robot.select(i)
  207.       robot.dropDown(robot.count(i)-1)
  208.       -- and drop all others
  209.       for j=empty_slot, INV_SIZE do
  210.         if robot.compareTo(j) then
  211.           robot.select(j)
  212.           robot.dropDown()
  213.           robot.select(i)
  214.         end
  215.       end
  216.     end
  217.   end
  218. end
  219.  
  220. -- ================================ M I N I N G ================================== --
  221. function qforward()
  222.   while not forward() do robot.swing() end
  223. end
  224.  
  225. function trash(side)
  226.   for i=1, trash_slots do
  227.     robot.select(i)
  228.     if side == sides.up then
  229.       a,t = robot.detectUp()
  230.       if t ~= 'solid' or robot.compareUp() then return true end
  231.     elseif side == sides.front then
  232.       a,t = robot.detect()
  233.       if t ~= 'solid' or robot.compare() then return true end
  234.     else
  235.       a,t = robot.detectDown()
  236.       if t ~= 'solid' or robot.compareDown() then return true end
  237.     end
  238.   end
  239.   return false
  240. end
  241.  
  242. function mine(side)
  243.   local direct = loc.d
  244.   local backdir = (direct+2)%4
  245.  
  246.   if side == sides.up then
  247.     c = 0
  248.     while not up() do
  249.       robot.swingUp()
  250.       c = c + 1
  251.       if c>DEAD_END then return end
  252.     end
  253.   elseif side == sides.front then
  254.     c = 0
  255.     while not forward() do
  256.       robot.swing()
  257.       c = c + 1
  258.       if c>DEAD_END then return end
  259.     end
  260.   elseif side == sides.down then
  261.     c = 0
  262.     while not down() do
  263.       robot.swingDown()
  264.       c = c + 1
  265.       if c>DEAD_END then return end
  266.     end
  267.   end
  268.  
  269.   lode[loc.x*MAX*MAX + loc.y*MAX + loc.z] = true
  270.  
  271.   -- check further direction
  272.   if lode[loc.x*MAX*MAX + loc.y*MAX + (loc.z+1)] == nil then
  273.     if not trash(sides.up) then mine(sides.up)
  274.     else lode[loc.x*MAX*MAX + loc.y*MAX + (loc.z+1)] = false end
  275.   end
  276.   if lode[loc.x*MAX*MAX + loc.y*MAX + (loc.z-1)] == nil then
  277.     if not trash(sides.down) then mine(sides.down)
  278.     else lode[loc.x*MAX*MAX + loc.y*MAX + (loc.z-1)] = false end
  279.   end
  280.  
  281.   for i=loc.d, loc.d+3 do
  282.     local a = i%4
  283.     local x = loc.x
  284.     local y = loc.y
  285.     if a == 0 then y = y + 1
  286.     elseif a == 1 then x = x + 1
  287.     elseif a == 2 then y = y - 1
  288.     else x = x - 1 end
  289.     if lode[x*MAX*MAX + y*MAX + loc.z] == nil then
  290.       while loc.d < a do turnRight() end
  291.       while loc.d > a do turnLeft() end
  292.       if not trash(sides.front) then mine(sides.front)
  293.       else lode[x*MAX*MAX + y*MAX + loc.z] = false end
  294.     end
  295.   end
  296.  
  297.   -- come back
  298.   if side == sides.up then
  299.     down()
  300.   elseif side == sides.front then
  301.     if loc.d == direct and back() then
  302.       -- yet ready =)
  303.     else
  304.       while loc.d < backdir do turnRight() end
  305.       while loc.d > backdir do turnLeft() end
  306.       qforward()
  307.     end
  308.   elseif side == sides.down then
  309.     up()
  310.   end
  311. end
  312.  
  313. function go(side)
  314.   direct = loc.d
  315.   lode = {}
  316.   mine(side)
  317.   while loc.d < direct do turnRight() end
  318.   while loc.d > direct do turnLeft() end
  319. end
  320.  
  321. function step(progress)
  322.   -- every tenth
  323.   tenth = (loc.x % 15 == 0)
  324.   -- dig one row
  325.   for x=1, w do
  326.     check_tool()
  327.     -- check up/down
  328.     if not trash(sides.down) then go(sides.down) end
  329.     if not trash(sides.up) then go(sides.up) end
  330.     check_tool()
  331.     -- tonnel for player
  332.     if PATHWAYS then
  333.       if loc.y == halfw then
  334.         robot.swingDown()
  335.         while robot.detectUp() do robot.swingUp() end
  336.       end
  337.       if x == 1 or x == w then
  338.         robot.swingDown()
  339.       end
  340.     else
  341.       if loc.y == halfw then
  342.         robot.swingDown()
  343.       end
  344.     end
  345.     -- move
  346.     if x<w then
  347.       qforward()
  348.       if PATHWAYS and tenth then robot.swingDown() end
  349.     end
  350.    
  351.   end
  352.  
  353.   -- check front
  354.   if not trash(sides.front) then go(sides.front) end
  355.  
  356.   -- next one
  357.   if progress%2==1 then
  358.     turnRight()
  359.     qforward()
  360.     turnRight()
  361.   else
  362.     turnLeft()
  363.     qforward()
  364.     turnLeft()
  365.   end
  366.  
  367.   -- fuel checking
  368.   check_fuel()
  369.   -- trash checking
  370.   if DROP_TRASH then
  371.     check_trash()
  372.   end
  373.   -- loot checking
  374.   if check_loot() then
  375.     turnAround()
  376.     placeChest()
  377.     unload()
  378.     grabChest()
  379.     turnAround()
  380.   end
  381.   --tool checking
  382.  
  383. end
  384.  
  385. function goBack()
  386.   while loc.y ~= 0 do
  387.     qforward()
  388.   end
  389.   if loc.d == 0 then turnLeft()
  390.   elseif loc.d == 2 then turnRight() end
  391.   while loc.x ~= 0 do
  392.     qforward()
  393.   end
  394.   turnRight()
  395. end
  396.  
  397. -- =================================== M A I N =================================== --
  398. print("Totoro Recursive Miner 1.5H")
  399. print("[INFO] Запуск. Длина: "..l..". Ширина: "..w..'. \n       Возврат: '..comeback)
  400. if cloader ~= nil and USE_CLOADER then
  401.   cloader.setActive(true)
  402.   print("[INFO] Чанклодер активирован.")
  403. end
  404. print("[INFO] Выключите робота, чтобы прервать работу.")
  405.  
  406. -- statistic value
  407. moves = 0
  408. -- main cycle
  409. robot.turnLeft()
  410. if light_allowed then robot.setLightColor(color.working) end
  411. for i=1, l do
  412.   step(i)
  413. end
  414.  
  415. -- ==================================== E N D ==================================== --
  416. -- move to start position
  417. if comeback == 'true' then goBack() end
  418. if light_allowed then robot.setLightColor(color.idle) end
  419. robot.turnRight()
  420.  
  421. if cloader ~= nil and USE_CLOADER then
  422.   cloader.setActive(false)
  423.   print("[INFO] Чанклодер деактивирован.")
  424. end
  425. print("[STATISTIC] Движений: "..moves)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement