Advertisement
MoonlightOwl

Totoro Recursive Miner 0.5H

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