Advertisement
UpZone

CC - Builder

Jun 18th, 2016
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.81 KB | None | 0 0
  1. ---------------
  2. -- BY UPZONE --
  3. ---------------
  4.  
  5. os.loadAPI("builder\\apis\\Colors")
  6. os.loadAPI("builder\\apis\\Paint")
  7. os.loadAPI("builder\\apis\\Turtle")
  8. os.loadAPI("builder\\apis\\Inventory")
  9. os.loadAPI("builder\\apis\\Button")
  10.  
  11. -- arguments
  12. local args = {...}
  13. local templatePath = args[1]
  14.  
  15. local width = nil
  16. local height = nil
  17.  
  18. local inventoryFields = {}
  19. local layers = {}
  20. local totalLayers = nil
  21.  
  22. local colorCount = {}
  23.  
  24. -- used for path finding
  25. local currentX = 1
  26. local currentY = 1
  27.  
  28. local front = 0
  29. local back = 1
  30. local right = 2
  31. local left = 3
  32.  
  33. local facing = front
  34.  
  35. -- validate
  36. term.clear()
  37. term.setCursorPos(1, 1)
  38.  
  39. if args[1] == nil or not fs.exists(args[1]) then
  40.     print("Usage: Builder <template path>")
  41.     return
  42. end
  43.  
  44. -- functions
  45. function loadTemplate(path)
  46.     -- read template
  47.     f = fs.open(path, "r")
  48.     content = f.readAll()
  49.     f.close()
  50.  
  51.     -- iterator function
  52.     splits = content:gmatch("([^\:]*)\:?")
  53.  
  54.     width = tonumber(splits())
  55.     height = tonumber(splits())
  56.    
  57.     -- which inventory slot has which color
  58.     idx = 0
  59.     for c in splits():gmatch(".") do
  60.         idx = idx + 1
  61.         if c ~= Colors.black then
  62.             if inventoryFields[c] == nil then
  63.                 inventoryFields[c] = {}
  64.             end
  65.             table.insert(inventoryFields[c], idx)
  66.         end
  67.     end
  68.    
  69.     -- rebuild layers
  70.     idx = 0
  71.     for c in splits():gmatch(".") do
  72.         idx = idx + 1
  73.    
  74.         -- layer
  75.         curLayer = math.floor(idx/(width * height)) + 1
  76.         if idx % (width * height) == 0 then
  77.             curLayer = curLayer - 1
  78.         end
  79.         if layers[curLayer] == nil then
  80.             layers[curLayer] = {}
  81.         end
  82.  
  83.         -- index on current layer
  84.         layerIdx = idx % (width * height)
  85.         if layerIdx == 0 then
  86.             layerIdx = (width * height)
  87.         end
  88.        
  89.         -- coordinate x on this layer
  90.         layerX = layerIdx % width
  91.         if layerX == 0 then
  92.             layerX = width
  93.         end
  94.  
  95.         -- coordinate y on this layer
  96.         layerY = math.ceil(layerIdx / width)
  97.         if layerY == 0 then
  98.             layerY = height
  99.         end
  100.         table.insert(layers[curLayer], { layerX, layerY, c, false })
  101.  
  102.         -- keep track of colors
  103.         if colorCount[c] == nil then
  104.             colorCount[c] = 0
  105.         end
  106.         colorCount[c] = colorCount[c] + 1
  107.     end
  108.  
  109.     totalLayers = table.getn(layers)
  110. end
  111.  
  112. function selectBlock(l, x, y)
  113.     -- current layer
  114.     layer = layers[l]
  115.  
  116.     -- get color for coordinate on this layer
  117.     color = nil
  118.     for k, v in ipairs(layer) do
  119.         if v[1] == x and v[2] == y then
  120.             color = v[3]
  121.             break
  122.         end
  123.     end
  124.  
  125.     -- ignore black (empty) fields
  126.     if color == Colors.black then
  127.         return false
  128.     end
  129.  
  130.     if color == nil then
  131.         error("No color found for corrdinate x: " .. x .. "/y: " .. y)
  132.     end
  133.  
  134.     -- get inventory slots associated with this color
  135.     slots = nil
  136.     for k, v in pairs(inventoryFields) do
  137.         if color == k then
  138.             slots = v
  139.         end
  140.     end
  141.  
  142.     if slots == nil then
  143.         error("No inventory slots found for this color! Adjust the template accordingly")
  144.     end
  145.  
  146.     while Inventory.getItemCount(slots) == 0 do
  147.         print("")
  148.         print("Run out of items! Please restock one of the following slots:")
  149.         for i, v in pairs(slots) do
  150.             term.write(v .. " ")
  151.         end
  152.         print("")
  153.         print("Waiting for 5 seconds to check again ...")
  154.         sleep(5)
  155.     end
  156.  
  157.     -- select an inventory slot of this color which has items
  158.     slot = nil
  159.     for k, v in pairs(slots) do
  160.         if turtle.getItemCount(v) > 0 then
  161.             slot = v
  162.             break
  163.         end
  164.     end
  165.  
  166.     if slot == nil then
  167.         error("No slot with items found for this color!")
  168.     end
  169.    
  170.     turtle.select(slot)
  171.  
  172.     return true
  173. end
  174.  
  175. function getDistance(x1, y1, x2, y2)
  176.     -- get distance between two points
  177.     xDistance = math.abs(x1 - x2)
  178.     yDistance = math.abs(y1 - y2)
  179.     return xDistance + yDistance
  180. end
  181.  
  182. function turnRight()
  183.     turtle.turnRight()
  184.  
  185.     -- keep track of turtle orientation for pathfinding
  186.     if facing == front then
  187.         facing = right
  188.     elseif facing == right then
  189.         facing = back
  190.     elseif facing == back then
  191.         facing = left
  192.     elseif facing == left then
  193.         facing = front
  194.     end
  195. end
  196.  
  197. function turnLeft()
  198.     turtle.turnLeft()
  199.  
  200.     -- keep track of turtle orientation for pathfinding
  201.     if facing == front then
  202.         facing = left
  203.     elseif facing == left then
  204.         facing = back
  205.     elseif facing == back then
  206.         facing = right
  207.     elseif facing == right then
  208.         facing = front
  209.     end
  210. end
  211.  
  212. function moveForward()
  213.     Turtle.moveForward()
  214.  
  215.     -- keep track of turtle orientation for pathfinding
  216.     if facing == front then
  217.         currentX = currentX + 1
  218.     elseif facing == left then
  219.         currentY = currentY - 1
  220.     elseif facing == back then
  221.         currentX = currentX - 1
  222.     elseif facing == right then
  223.         currentY = currentY + 1
  224.     end
  225. end
  226.  
  227. function gotoX(x)
  228.     if x < currentX then
  229.         if facing == front then
  230.             turnRight()
  231.             turnRight()
  232.         elseif facing == left then
  233.             turnLeft()
  234.         elseif facing == right then
  235.             turnRight()
  236.         end
  237.         while x < currentX do
  238.             moveForward()
  239.         end
  240.     elseif x > currentX then
  241.         if facing == back then
  242.             turnRight()
  243.             turnRight()
  244.         elseif facing == left then
  245.             turnRight()
  246.         elseif facing == right then
  247.             turnLeft()
  248.         end
  249.         while x > currentX do
  250.             moveForward()
  251.         end
  252.     end
  253. end
  254.  
  255. function gotoY(y)
  256.     if y < currentY then
  257.         if facing == front then
  258.             turnLeft()
  259.         elseif facing == right then
  260.             turnRight()
  261.             turnRight()
  262.         elseif facing == back then
  263.             turnRight()
  264.         end
  265.         while y < currentY do
  266.             moveForward()
  267.         end
  268.     elseif y > currentY then
  269.         if facing == front then
  270.             turnRight()
  271.         elseif facing == left then
  272.             turnLeft()
  273.             turnLeft()
  274.         elseif facing == back then
  275.             turnLeft()
  276.         end
  277.         while y > currentY do
  278.             moveForward()
  279.         end
  280.     end
  281. end
  282.  
  283. function goto(x, y)
  284.     gotoX(x)
  285.     gotoY(y)
  286. end
  287.  
  288. function placeClosestBlock(l, blocksToIgnore)
  289.     local closestDistance = nil
  290.     local closestSpot = nil
  291.    
  292.     for k, v in ipairs(layers[l]) do
  293.         -- spot has not been placed yet
  294.         if not v[4] then
  295.             -- color is not one to ignore
  296.             local ignore = false
  297.             for s, t in pairs(blocksToIgnore) do
  298.                 if v[3] == t then
  299.                     ignore = true
  300.                     break
  301.                 end
  302.             end
  303.             if not ignore then
  304.                 -- check distance
  305.                 local distance = getDistance(currentX, currentY, v[1], v[2])
  306.                 if closestDistance == nil or distance < closestDistance then
  307.                     closestDistance = distance
  308.                     closestSpot = k
  309.                     if closestDistance == 1 then
  310.                         break
  311.                     end
  312.                 end
  313.             end
  314.         end
  315.     end
  316.  
  317.     if closestSpot ~= nil then
  318.         layers[l][closestSpot][4] = true
  319.         local x = layers[l][closestSpot][1]
  320.         local y = layers[l][closestSpot][2]
  321.         goto(x, y)
  322.         local placeBlock = selectBlock(l, x, y)
  323.         if placeBlock then
  324.             Turtle.placeDown()
  325.         end
  326.         return true
  327.     else
  328.         return false
  329.     end
  330. end
  331.  
  332. function startMain()
  333.     for l = 1, totalLayers do
  334.         print("Starting layer " .. l)
  335.         Turtle.moveUp()
  336.  
  337.         -- place all blocks except black and yellow
  338.         while placeClosestBlock(l, {Colors.black, Colors.yellow}) do end
  339.  
  340.         -- place yellow blocks
  341.         while placeClosestBlock(l, {Colors.white, Colors.orange, Colors.magenta, Colors.lightBlue, Colors.lime, Colors.pink, Colors.pink, Colors.gray, Colors.lightGray, Colors.cyan, Colors.purple,                Colors.blue, Colors.brown, Colors.green, Colors.red, Colors.black}) do end
  342.     end
  343. end
  344.  
  345. -- initializing
  346. loadTemplate(templatePath)
  347.  
  348. print("Prepare your inventory slots defined by the template like so: ")
  349. print("")
  350.  
  351. btnStart = Button.create("Start", 32, 10, 7, 3, startMain, Colors.white, Colors.red, Colors.white, Colors.lime)
  352. btnStart:draw()
  353.  
  354. while true do
  355.     idx = 3
  356.     for i, k in pairs(inventoryFields) do
  357.         idx = idx + 1
  358.         term.setCursorPos(2, idx)
  359.         Paint.pixel(2, idx, " ", Colors.black, i)
  360.         term.setCursorPos(4, idx)
  361.         term.write("= Slot(s): ")
  362.         for j, h in pairs(k) do
  363.             term.write(h .. " ")
  364.         end
  365.         Inventory.itemCountStatus(colorCount[i], k)    
  366.     end
  367.  
  368.     timeout = os.startTimer(3)
  369.     event = {os.pullEvent()}
  370.     if event[1] == "mouse_click" and btnStart:intersects(event[3], event[4]) then
  371.         btnStart:raiseOnClick()
  372.         break
  373.     end
  374.  
  375.     sleep(0)
  376. end
  377.  
  378. -- finish
  379. goto(1, 1)
  380. print("Builder finished!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement