Advertisement
BombBloke

mapArt (ComputerCraft)

Aug 2nd, 2017
1,992
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 27.93 KB | None | 1 0
  1. -- +--------------------------------------------------------+
  2. -- |                                                        |
  3. -- |                         mapArt                         |
  4. -- |                                                        |
  5. -- +--------------------------------------------------------+
  6.  
  7. local version = "Version 1.1.1"
  8.  
  9. -- By Jeffrey Alexander, aka Bomb Bloke.
  10. -- Command Computer script for building map images out of GIFs.
  11. -- http://www.computercraft.info/forums2/index.php?/topic/28883-mapart/
  12.  
  13. ---------------------------------------------
  14. ------------      Load APIs      ------------
  15. ---------------------------------------------
  16.  
  17. local function loadAPI(API, paste)
  18.     if not _G[API] then
  19.         if not (fs.exists(API) or fs.exists(shell.resolve(API))) then
  20.             shell.run("pastebin get " .. paste .. " " .. API)
  21.             os.loadAPI(shell.resolve(API))
  22.         else os.loadAPI(fs.exists(API) and API or shell.resolve(API)) end
  23.     end
  24. end
  25.  
  26. loadAPI("bbpack", "cUYTGbpb")
  27. loadAPI("GIF",    "5uk9uRjC")
  28.  
  29. ---------------------------------------------
  30. ------------Variable Declarations------------
  31. ---------------------------------------------
  32.  
  33. local teleport = {commands.exec("tpn")}
  34. teleport = (teleport[2][1]:sub(1, 16) == "Unknown command.") and "teleport" or "tpn"
  35.  
  36. local transparent = "minecraft:sandstone"
  37.  
  38. local x, y, z = commands.getBlockPosition()
  39. local x1, z1 = math.floor((x - 64) / 128) * 128 + 64, math.floor((z - 64) / 128) * 128 + 64
  40. local xSize, ySize, myEvent = term.getSize()
  41. local startDir = shell.resolve(".")
  42.  
  43. ---------------------------------------------
  44. ------------      Functions      ------------
  45. ---------------------------------------------
  46.  
  47. local function clear(textCol, backCol)
  48.     if textCol then term.setTextColour(textCol) end
  49.     if backCol then term.setBackgroundColour(backCol) end
  50.     for i = 4, ySize - 3 do
  51.         term.setCursorPos(1, i)
  52.         term.clearLine()
  53.     end
  54. end
  55.  
  56. local function snooze()
  57.     local myEvent = tostring({})
  58.     os.queueEvent(myEvent)
  59.     os.pullEvent(myEvent)
  60. end
  61.  
  62. -- Returns whether a click was performed at a given location.
  63. -- If one parameter is passed, it checks to see if y is [1].
  64. -- If two parameters are passed, it checks to see if x is [1] and y is [2].
  65. -- If three parameters are passed, it checks to see if x is between [1]/[2] (non-inclusive) and y is [3].
  66. -- If four paramaters are passed, it checks to see if x is between [1]/[2] and y is between [3]/[4] (non-inclusive).
  67. local function clickedAt(...)
  68.     if myEvent[1] ~= "mouse_click" then return false end
  69.     if #arg == 1 then return (arg[1] == myEvent[4])
  70.     elseif #arg == 2 then return (myEvent[3] == arg[1] and myEvent[4] == arg[2])
  71.     elseif #arg == 3 then return (myEvent[3] > arg[1] and myEvent[3] < arg[2] and myEvent[4] == arg[3])
  72.     else return (myEvent[3] > arg[1] and myEvent[3] < arg[2] and myEvent[4] > arg[3] and myEvent[4] < arg[4]) end
  73. end
  74.  
  75. -- Returns whether one of a given set of keys was pressed.
  76. local function pressedKey(...)
  77.     if myEvent[1] ~= "key" then return false end
  78.     for i=1,#arg do if arg[i] == myEvent[2] then return true end end
  79.     return false
  80. end
  81.  
  82. -- Prompts user to select a file.
  83. local function fileBrowser()
  84.     local bump = math.floor((xSize - 49) / 2) + 1
  85.     local cursor = {{">>  ","  <<"},{"> > "," < <"},{" >> "," << "},{"> > "," < <"}}
  86.     local blackText = (_CC_VERSION or _HOST) and colours.grey or colours.black
  87.  
  88.     while true do
  89.         local displayList, position, lastPosition, animationTimer, curCount, gapTimer, lastProgress = {}, 1, 0, os.startTimer(0), 1
  90.         if #shell.resolve(".") > 0 then displayList[1] = ".." end
  91.  
  92.         do
  93.             local fullList = fs.list(shell.resolve("."))
  94.             table.sort(fullList, function (a, b) return string.lower(a) < string.lower(b) end)
  95.             for i = 1, #fullList do if fs.isDir(shell.resolve(fullList[i])) then displayList[#displayList + 1] = fullList[i] end end
  96.             for i = 1, #fullList do if fullList[i]:sub(#fullList[i] - 3):lower() == ".gif" then displayList[#displayList + 1] = fs.getName(fullList[i]) end end
  97.         end
  98.  
  99.         while true do
  100.             myEvent = {os.pullEvent()}
  101.  
  102.             -- Track animations (bouncing cursor + scrolling marquee).
  103.             if myEvent[1] == "timer" and myEvent[2] == animationTimer then
  104.                 curCount = curCount == 4 and 1 or (curCount + 1)
  105.                 animationTimer = os.startTimer(0.5)
  106.                 myEvent[1] = "cabbage"
  107.  
  108.             -- Bail.
  109.             elseif pressedKey(keys.backspace) or (myEvent[1] == "mouse_click" and myEvent[2] == 2) then
  110.                 return nil
  111.  
  112.             -- Move down the list.
  113.             elseif pressedKey(keys.down, keys.s) or (myEvent[1] == "mouse_scroll" and myEvent[2] == 1) then
  114.                 position = position == #displayList and 1 or (position + 1)
  115.  
  116.             -- Move up the list.
  117.             elseif pressedKey(keys.up, keys.w) or (myEvent[1] == "mouse_scroll" and myEvent[2] == -1) then
  118.                 position = position == 1 and #displayList or (position - 1)
  119.  
  120.             -- Select something.
  121.             elseif pressedKey(keys.enter, keys.space) or clickedAt(math.floor(ySize / 2) + 1) then
  122.                 if fs.isDir(shell.resolve(displayList[position])) then
  123.                     shell.setDir(shell.resolve(displayList[position]))
  124.                     break
  125.                 else return shell.resolve(displayList[position]) end
  126.            
  127.             -- User clicked somewhere on the file list; move that entry to the currently-selected position.
  128.             elseif clickedAt(0, xSize + 1, 3, ySize - 2) then
  129.                 position = position + myEvent[4] - math.floor(ySize / 2) - 1
  130.                 position = position > #displayList and #displayList or position
  131.                 position = position < 1 and 1 or position
  132.             end
  133.  
  134.             -- Update other screen stuff.
  135.             if myEvent[1] ~= "timer" then
  136.                 -- File list.
  137.                 term.setBackgroundColour(colours.black)
  138.                 for y = position == lastPosition and (math.floor(ySize / 2) + 1) or 4, position == lastPosition and (math.floor(ySize / 2) + 1) or (ySize - 3) do
  139.                     local thisLine = y + position - math.floor(ySize / 2) - 1
  140.  
  141.                     if displayList[thisLine] then
  142.                         local thisString = displayList[thisLine]
  143.                         thisString = fs.isDir(shell.resolve(thisString)) and "["..thisString.."]" or thisString:sub(1, #thisString-4)
  144.  
  145.                         if thisLine == position then
  146.                             term.setCursorPos(math.floor((xSize - #thisString - 8) / 2) + 1, y)
  147.                             term.clearLine()
  148.                             term.setTextColour(colours.red)
  149.                             term.write(cursor[curCount][1])
  150.                             term.setTextColour(colours.orange)
  151.                             term.write(thisString)
  152.                             term.setTextColour(colours.red)
  153.                             term.write(cursor[curCount][2])
  154.                         else
  155.                             term.setCursorPos(math.floor((xSize - #thisString) / 2) + 1, y)
  156.                             term.clearLine()
  157.  
  158.                             if y == 4 or y == ySize - 3 then
  159.                                 term.setTextColour(blackText)
  160.                             elseif y == 5 or y == ySize - 4 then
  161.                                 term.setTextColour(term.isColour() and colours.grey or blackText)
  162.                             elseif y == 6 or y == ySize - 5 then
  163.                                 term.setTextColour(term.isColour() and colours.lightGrey or colours.white)
  164.                             else term.setTextColour(colours.white) end
  165.  
  166.                             term.write(thisString)
  167.                         end
  168.                     else
  169.                         term.setCursorPos(1, y)
  170.                         term.clearLine()
  171.                     end
  172.                 end
  173.  
  174.                 lastPosition = position
  175.             end
  176.         end
  177.     end
  178. end
  179.  
  180. -- Constructs image within the world.
  181. local function doBuild(filename)
  182.     local GIFImage, mapsX, mapsY, buildCount, myTimer = GIF.loadGIF(filename, "mapArt.pal"), 1, 1, 1
  183.     local vert = GIFImage.height > GIFImage.width
  184.    
  185.     if vert then
  186.         mapsX = math.ceil(GIFImage.width * mapsY / GIFImage.height)
  187.     else
  188.         mapsY = math.ceil(GIFImage.height * mapsX / GIFImage.width)
  189.     end
  190.    
  191.     -- Bug the user about the output size:
  192.     while true do
  193.         clear(colours.black, colours.lightGrey)
  194.         term.setCursorPos(21, 5)
  195.         term.write("Resolution")
  196.         term.setTextColour(colours.grey)
  197.         term.setCursorPos(5, 7)
  198.         term.write("Image resolution: " .. GIFImage.width .. " x " .. GIFImage.height .. ", ratio: " .. (GIFImage.width / GIFImage.height))
  199.         term.setCursorPos(5, 9)
  200.         term.write("Map resolution: " .. (mapsX * 128) .. " x " .. (mapsY * 128) .. ", ratio: " .. (mapsX / mapsY))
  201.         term.setCursorPos(5, 11)
  202.         term.write("Columns:")
  203.         term.setCursorPos(5, 13)
  204.         term.write("Rows:")
  205.         term.setCursorPos(16, 11)
  206.         term.write(mapsX)
  207.         term.setCursorPos(16, 13)
  208.         term.write(mapsY)
  209.         term.setCursorPos(41, 11)
  210.         term.write("Start")
  211.         term.setCursorPos(39, 12)
  212.         term.write("from map:")
  213.         term.setCursorPos(42, 13)
  214.         term.write(buildCount)
  215.        
  216.         term.setTextColour(colours.lightGrey)
  217.         term.setBackgroundColour(colours.blue)
  218.         term.setCursorPos(14, vert and 13 or 11)
  219.         term.write("<")
  220.         term.setCursorPos(19, vert and 13 or 11)
  221.         term.write(">")
  222.         term.setCursorPos(40, 13)
  223.         term.write("<")
  224.         term.setCursorPos(46, 13)
  225.         term.write(">")
  226.         term.setCursorPos(5, 15)
  227.         term.write(" Back ")
  228.         term.setCursorPos(40, 15)
  229.         term.write(" Begin ")
  230.        
  231.         myEvent = {os.pullEvent()}
  232.        
  233.         if clickedAt(14, vert and 13 or 11) then
  234.             if vert and mapsY > 1 then
  235.                 mapsY = mapsY - 1
  236.                 mapsX = math.ceil(GIFImage.width * mapsY / GIFImage.height)
  237.             elseif not vert and mapsX > 1 then
  238.                 mapsX = mapsX - 1
  239.                 mapsY = math.ceil(GIFImage.height * mapsX / GIFImage.width)
  240.             end
  241.             if buildCount > mapsX * mapsY then buildCount = mapsX * mapsY end
  242.         elseif clickedAt(19, vert and 13 or 11) then
  243.             if vert and mapsY < 100 then
  244.                 mapsY = mapsY + 1
  245.                 mapsX = math.ceil(GIFImage.width * mapsY / GIFImage.height)
  246.             elseif not vert and mapsX < 100 then
  247.                 mapsX = mapsX + 1
  248.                 mapsY = math.ceil(GIFImage.height * mapsX / GIFImage.width)
  249.             end
  250.         elseif clickedAt(40, 13) and buildCount > 1 then
  251.             buildCount = buildCount - 1
  252.         elseif clickedAt(46, 13) and buildCount < mapsX * mapsY then
  253.             buildCount = buildCount + 1
  254.         elseif clickedAt(4, 11, 15) then
  255.             return
  256.         elseif clickedAt(39, 47, 15) then
  257.             break
  258.         end
  259.     end
  260.    
  261.     clear(colours.black, colours.lightGrey)
  262.    
  263.     term.setCursorPos(21, 5)
  264.     term.write("Resizing...")
  265.    
  266.     for i = 2, #GIFImage do GIFImage[i] = nil end
  267.    
  268.     if GIFImage.width ~= mapsX * 128 and GIFImage.height ~= mapsY * 128 then
  269.         if GIFImage.height > GIFImage.width then
  270.             GIFImage = GIF.resizeGIF(GIFImage, nil, mapsY * 128)
  271.         else
  272.             GIFImage = GIF.resizeGIF(GIFImage, mapsX * 128)
  273.         end
  274.     end
  275.    
  276.     local image = {}
  277.     for y = 1, GIFImage.height do
  278.         image[y] = {}
  279.         for x = 1, GIFImage.width do image[y][x] = 0 end
  280.     end
  281.    
  282.     local pal, width, height = GIFImage.pal, GIFImage.width, GIFImage.height
  283.     local len = #pal / 3
  284.     GIFImage = GIFImage[1]
  285.  
  286.     for y = 1, GIFImage.yend do
  287.         local x, GIFImageY, imageY = GIFImage.xstart + 1, GIFImage[y], image[y + GIFImage.ystart]
  288.         for i = 1, #GIFImageY do
  289.             local GIFImageYI = GIFImageY[i]
  290.             if type(GIFImageYI) == "number" then
  291.                 x = x + GIFImageYI
  292.             else
  293.                 for pixel = 1, #GIFImageYI do imageY[x + pixel - 1] = GIFImageYI[pixel] end
  294.                 x = x + #GIFImageYI
  295.             end
  296.         end
  297.     end
  298.    
  299.     GIFImage = nil
  300.    
  301.     term.setCursorPos(21, 7)
  302.     term.write("Padding...")
  303.    
  304.     if width < mapsX * 128 then
  305.         local diff = mapsX * 128 - width
  306.         for y = 1, height do
  307.             local row = image[y]
  308.             for i = 1, math.floor(diff / 2) do table.insert(row, 1, 0) end
  309.             for i = #row + 1, #row + math.ceil(diff / 2) do row[i] = 0 end
  310.             snooze()
  311.         end
  312.         width = mapsX * 128
  313.     end
  314.    
  315.     if height < mapsY * 128 then
  316.         local row = {}
  317.         for i = 1, mapsX * 128 do row[i] = 0 end
  318.         local diff = mapsY * 128 - height
  319.         for i = 1, math.floor(diff / 2) do table.insert(image, 1, row) end
  320.         for i = #image + 1, #image + math.ceil(diff / 2) do image[i] = row end
  321.         height = mapsY * 128
  322.         snooze()
  323.     end
  324.    
  325.     -- Build stuff!
  326.     for builds = buildCount, mapsX * mapsY do
  327.         local xxxx, zzzz, curCommands, maxCommands, counter = (builds - 1) % mapsX, math.floor((builds - 1) / mapsX), 0, 250, 0
  328.        
  329.         clear(colours.black, colours.lightGrey)
  330.         term.setCursorPos(22, 5)
  331.         term.write("Building")
  332.         term.setBackgroundColour(colours.grey)
  333.         term.setCursorPos(4, 11)
  334.         term.write(string.rep(" ", 45))
  335.         term.setTextColour(colours.grey)
  336.         term.setBackgroundColour(colours.lightGrey)
  337.  
  338.         sleep(0)
  339.        
  340.         parallel.waitForAny(
  341.             -- Track completed commands.
  342.             function()
  343.                 while true do
  344.                     os.pullEvent("task_complete")
  345.                     curCommands = curCommands - 1
  346.                 end
  347.             end,
  348.            
  349.             -- Display build progress.
  350.             -- Mostly pointless because server time pretty much stands still while this is running.
  351.             function()
  352.                 local countmax, lastcount = 16640, 0
  353.  
  354.                 repeat
  355.                     myTimer = os.startTimer(60)
  356.                     repeat local event, id = os.pullEvent("timer") until id == myTimer
  357.  
  358.                     term.setBackgroundColour(colours.brown)
  359.                     term.setCursorPos(4, 11)
  360.                     term.write(string.rep(" ", math.floor(counter / countmax * 45)))
  361.                     term.setBackgroundColour(colours.grey)
  362.                     term.write(string.rep(" ", 45 - math.floor(counter / countmax * 45)))
  363.  
  364.                     term.setBackgroundColour(colours.lightGrey)
  365.                     term.setCursorPos(4, 7)
  366.                     term.clearLine()
  367.                     term.write(tostring(counter) .. " / " .. tostring(countmax) .. " blocks" .. (counter < countmax and ", ~" .. tostring(counter - lastcount) .. " per minute." or "."))
  368.                     term.setCursorPos(4, 9)
  369.                     term.clearLine()
  370.                     term.write(counter < countmax and tostring(math.floor(counter / countmax * 100)) .. "%, about " .. tostring(math.ceil((countmax - counter) / (counter - lastcount))) .. " minutes remaining." or "100%")
  371.  
  372.                     lastcount = counter
  373.                 until counter == countmax
  374.             end,
  375.            
  376.             -- Actual construction is done here.
  377.             function()
  378.                 -- Prevent too many commands executing at once.
  379.                 local function doCommand(doThis)
  380.                     while curCommands >= maxCommands do os.pullEvent("task_complete") end
  381.                     commands.execAsync(doThis)
  382.                     curCommands = curCommands + 1
  383.                     counter = counter + 1
  384.                 end
  385.                
  386.                 -- Clear old builds.
  387.                 doCommand("fill " .. x1 .. " 127 " .. (z1 - 1) .. " " .. (x1 + 127) .. " 128 " .. z1 .. " minecraft:air")
  388.                 for i = 1, 127 do doCommand("fill " .. x1 .. " " .. (127 - i) .. " " .. (z1 + i) .. " " .. (x1 + 127) .. " " .. (128 + i) .. " " .. (z1 + i) .. " minecraft:air") end
  389.                
  390.                 -- Calibrate wave heights.
  391.                 local ys = {}
  392.                 for i = 1, 128 do
  393.                     local y = (math.floor((image[1 + zzzz * 128][i + xxxx * 128] - 1) / len) == 0) and 127 or 128
  394.                     doCommand("setblock " .. (x1 + i - 1) .. " " .. y .. " " .. (z1 - 1) .. " minecraft:cobblestone")
  395.                     ys[i] = y
  396.                 end
  397.                
  398.                 -- Main image area.
  399.                 for xxx = 0, 7 do for zzz = 0, 7 do for xx = 1, 16 do
  400.                     local y = ys[xxx * 16 + xx]
  401.                    
  402.                     for zz = 1, 16 do
  403.                         local curCol = image[zz + zzz * 16 + zzzz * 128][xx + xxx * 16 + xxxx * 128]
  404.                         local block = pal[curCol]
  405.                        
  406.                         local shade = math.floor((curCol - 1) / len)
  407.                         if shade == 0 then
  408.                             y = y + 1
  409.                         elseif shade == 2 then
  410.                             y = y - 1
  411.                         end
  412.                        
  413.                         doCommand("setblock " .. (x1 + xx - 1 + xxx * 16) .. " " .. y .. " " .. (z1 + zz - 1 + zzz * 16) .. " " .. block[4] .. " " .. block[5])
  414.                     end
  415.                    
  416.                     ys[xxx * 16 + xx] = y
  417.                 end end end
  418.                
  419.                 os.queueEvent("timer", myTimer)
  420.                 while true do os.pullEvent("stopResumingMe") end
  421.             end
  422.         )
  423.        
  424.         commands.give("@p minecraft:map")
  425.        
  426.         term.setCursorPos(4, 13)
  427.         term.write("Completed build " .. builds.. " of " .. (mapsX * mapsY) .. ".")
  428.        
  429.         term.setTextColour(colours.lightGrey)
  430.         term.setBackgroundColour(colours.blue)
  431.         term.setCursorPos(5, 15)
  432.         term.write(" Cancel ")
  433.         term.setCursorPos(37, 15)
  434.         term.write(" Continue ")
  435.        
  436.         while true do
  437.             myEvent = {os.pullEvent("mouse_click")}
  438.            
  439.             if clickedAt(4, 13, 15) then
  440.                 return
  441.             elseif clickedAt(36, 47, 15) then
  442.                 break
  443.             end
  444.         end
  445.     end
  446. end
  447.  
  448. ---------------------------------------------
  449. ------------         Init        ------------
  450. ---------------------------------------------
  451.  
  452. if not os.getComputerLabel() then os.setComputerLabel("mapArt") end
  453.  
  454. term.setTextColour(colours.black)
  455. term.setBackgroundColour(colours.brown)
  456.  
  457. for j = 0, 1 do for i = 1, 3 do
  458.     term.setCursorPos(1, i + (j * (ySize - 3)))
  459.     term.clearLine()
  460. end end
  461.  
  462. term.setCursorPos(5, 2)
  463. term.write("mapArt")
  464. term.setCursorPos(2, ySize - 1)
  465. term.write("This system is facing "..({"unknown", "north", "south", "west", "east"})[commands.getBlockInfo(commands.getBlockPosition()).metadata]..".")
  466.  
  467. paintutils.drawPixel(1, 1, colours.blue)
  468. paintutils.drawPixel(2, 1, colours.green)
  469. paintutils.drawPixel(3, 1, colours.yellow)
  470. paintutils.drawPixel(1, 2, colours.grey)
  471. paintutils.drawPixel(2, 2, colours.white)
  472. paintutils.drawPixel(3, 2, colours.lightBlue)
  473. paintutils.drawPixel(1, 3, colours.orange)
  474. paintutils.drawPixel(2, 3, colours.lime)
  475. paintutils.drawPixel(3, 3, colours.red)
  476.  
  477. -- Build a palette file suitable for the current MC install:
  478. if not fs.exists("mapArt.pal") then
  479.     -- All colours as of MC1.12,
  480.     -- except the first, which is prone to change,
  481.     -- and water, which doesn't work well with staircasing:
  482.     local basePal = {
  483.         {127, 178,  56, "minecraft:grass"},
  484.         {247, 233, 163, "minecraft:sandstone"},
  485.         {199, 199, 199, "minecraft:web"},
  486.         {255,   0,   0, "minecraft:redstone_block"},
  487.         {160, 160, 255, "minecraft:packed_ice"},
  488.         {167, 167, 167, "minecraft:iron_block"},
  489.         {  0, 124,   0, "minecraft:leaves"},
  490.         {255, 255, 255, "minecraft:wool"},
  491.         {164, 168, 184, "minecraft:clay"},
  492.         {151, 109,  77, "minecraft:planks", 3},
  493.         {112, 112, 112, "minecraft:cobblestone"},
  494.         {143, 119,  72, "minecraft:planks"},
  495.         {255, 252, 245, "minecraft:stone", 3},
  496.         {216, 127,  51, "minecraft:planks", 4},
  497.         {178,  76, 216, "minecraft:wool", 2},
  498.         {102, 153, 216, "minecraft:wool", 3},
  499.         {229, 229,  51, "minecraft:wool", 4},
  500.         {127, 204,  25, "minecraft:wool", 5},
  501.         {242, 127, 165, "minecraft:wool", 6},
  502.         { 76,  76,  76, "minecraft:wool", 7},
  503.         {153, 153, 153, "minecraft:wool", 8},
  504.         { 76, 127, 153, "minecraft:wool", 9},
  505.         {127,  63, 178, "minecraft:wool", 10},
  506.         { 51,  76, 178, "minecraft:wool", 11},
  507.         {102,  76,  51, "minecraft:planks", 5},
  508.         {102, 127,  51, "minecraft:wool", 13},
  509.         {153,  51,  51, "minecraft:wool", 14},
  510.         { 25,  25,  25, "minecraft:wool", 15},
  511.         {250, 238,  77, "minecraft:gold_block"},
  512.         { 92, 219, 213, "minecraft:diamond_block"},
  513.         { 74, 128, 255, "minecraft:lapis_block"},
  514.         {  0, 217,  58, "minecraft:emerald_block"},
  515.         {129,  86,  49, "minecraft:planks", 1},
  516.         {112,   2,   0, "minecraft:netherrack"},
  517.         {209, 177, 161, "minecraft:stained_hardened_clay"},
  518.         {159,  82,  36, "minecraft:stained_hardened_clay", 1},
  519.         {149,  87, 108, "minecraft:stained_hardened_clay", 2},
  520.         {112, 108, 138, "minecraft:stained_hardened_clay", 3},
  521.         {186, 133,  36, "minecraft:stained_hardened_clay", 4},
  522.         {103, 117,  53, "minecraft:stained_hardened_clay", 5},
  523.         {160,  77,  78, "minecraft:stained_hardened_clay", 6},
  524.         { 57,  41,  35, "minecraft:stained_hardened_clay", 7},
  525.         {135, 107,  98, "minecraft:stained_hardened_clay", 8},
  526.         { 87,  92,  92, "minecraft:stained_hardened_clay", 9},
  527.         {122,  73,  88, "minecraft:stained_hardened_clay", 10},
  528.         { 76,  62,  92, "minecraft:stained_hardened_clay", 11},
  529.         { 76,  50,  35, "minecraft:stained_hardened_clay", 12},
  530.         { 76,  82,  42, "minecraft:stained_hardened_clay", 13},
  531.         {142,  60,  46, "minecraft:stained_hardened_clay", 14},
  532.         { 37,  22,  16, "minecraft:stained_hardened_clay", 15}
  533.     }
  534.    
  535.     -- Remove anything we can't setblock:
  536.     for i = #basePal, 1, -1 do
  537.         local this = basePal[i]
  538.         if not this[5] then this[5] = 0 end
  539.  
  540.         commands.setblock(x, y + 1, z, this[4],this[5])
  541.         local data = commands.getBlockInfo(x, y + 1, z)
  542.         if data.name ~= this[4] or data.metadata ~= this[5] then table.remove(basePal, i) end
  543.     end
  544.    
  545.     -- If we can't setblock glazed terracotta, also remove regular terracotta (it has no special colour prior to MC1.12):
  546.     commands.setblock(x, y + 1, z, "minecraft:white_glazed_terracotta")
  547.     if basePal[#basePal][4] == "minecraft:stained_hardened_clay" and commands.getBlockInfo(x, y + 1, z).name ~= "minecraft:white_glazed_terracotta" then for i = #basePal - 15, #basePal do basePal[i] = nil end end
  548.    
  549.     commands.setblock(x, y + 1, z, "minecraft:air")
  550.    
  551.     -- Triplicate the entries to get the three different shades:
  552.     local len = #basePal
  553.     for i = 1, len do
  554.         local old, new1, new2 = basePal[i], {}, {}
  555.        
  556.         new1[1], new1[2], new1[3] = math.floor(old[1] * 220 / 255), math.floor(old[2] * 220 / 255), math.floor(old[3] * 220 / 255)
  557.         new2[1], new2[2], new2[3] = math.floor(old[1] * 180 / 255), math.floor(old[2] * 180 / 255), math.floor(old[3] * 180 / 255)
  558.         new1[4], new1[5], new2[4], new2[5] = old[4], old[5], old[4], old[5]
  559.        
  560.         basePal[i + len], basePal[i + 2 * len] = new1, new2
  561.     end
  562.    
  563.     basePal[0] = {1000, 1000, 1000, transparent, 0}
  564.    
  565.     -- Save for future reference:
  566.     local output = fs.open("mapArt.pal", "w")
  567.     output.write(textutils.serialise(basePal))
  568.     output.close()
  569. end
  570.  
  571. local myLoc = "My location: X: " .. x .. ", Y: " .. y .. ", Z: " .. z
  572. local buildArea = "Build area: X: " .. (x1 - 4) .. " - " .. (x1 + 131).. ", Z: " .. (z1 - 4) .. " - " .. (z1 + 131)
  573.  
  574. local ready = (x == x1 + 64 and y == 1 and z == z1 + 63)
  575.  
  576. ---------------------------------------------
  577. ------------  Main Program Loop  ------------
  578. ---------------------------------------------
  579.  
  580. while true do
  581.     clear(colours.black, colours.lightGrey)
  582.  
  583.     term.setCursorPos(22, 5)
  584.     term.write("What Do?")
  585.    
  586.     term.setCursorPos(math.floor((xSize - #myLoc) / 2) + 1, 14)
  587.     term.write(myLoc)
  588.     term.setCursorPos(math.floor((xSize - #buildArea) / 2) + 1, 15)
  589.     term.write(buildArea)
  590.    
  591.     term.setTextColour(colours.lightGrey)
  592.     term.setBackgroundColour(colours.grey)
  593.    
  594.     term.setCursorPos(21, 8)
  595.     if ready then
  596.         term.write("  Build   ")
  597.         term.setCursorPos(21, 10)
  598.         term.write("   Fill   ")
  599.     else
  600.         term.write(" Prepare  ")
  601.     end
  602.    
  603.     term.setCursorPos(21, 12)
  604.     term.write("   Quit   ")
  605.    
  606.     myEvent = {os.pullEvent()}
  607.    
  608.     if clickedAt(20, 31, 8) then
  609.         if ready then
  610.             -- Build something.
  611.             local filename = fileBrowser()
  612.             if filename then doBuild(filename) end
  613.         else
  614.             -- Prepare build area.
  615.            
  616.             -- Safe room:
  617.             commands.execAsync("fill " .. (x1 + 59) .. " 0 " .. (z1 + 59) .. " " .. (x1 + 68) .. " 5 " .. (z1 + 68) .. " minecraft:bedrock")
  618.             commands.execAsync("fill " .. (x1 + 60) .. " 1 " .. (z1 + 60) .. " " .. (x1 + 67) .. " 4 " .. (z1 + 67) .. " minecraft:air")
  619.             commands.execAsync("setblock " .. (x1 + 63) .. " 1 " .. (z1 + 63) .. " minecraft:ender_chest 3")
  620.             commands.execAsync("setblock " .. (x1 + 64) .. " 1 " .. (z1 + 63) .. " minecraft:bedrock")
  621.             commands.execAsync("setblock " .. (x1 + 64) .. " 2 " .. (z1 + 63) .. " minecraft:torch 5")
  622.             commands.execAsync(teleport .. " @p " .. (x1 + 64) .. " 2 " .. (z1 + 65))
  623.            
  624.             -- Empty out the surrounding chunks:
  625.             for yy = 255, 3, -1 do if yy ~= y then commands.execAsync("fill " .. (x1 - 4) .. " " .. yy .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. yy .. " " .. (z1 + 131) .. " minecraft:air") end end
  626.             commands.execAsync("fill " .. (x1 - 4) .. " 0 " .. (z1 - 4) .. " " .. (x1 + 67) .. " 2 " .. (z1 + 59) .. " minecraft:air")
  627.             commands.execAsync("fill " .. (x1 + 68) .. " 0 " .. (z1 - 4) .. " " .. (x1 + 131) .. " 2 " .. (z1 + 67) .. " minecraft:air")
  628.             commands.execAsync("fill " .. (x1 + 60) .. " 0 " .. (z1 + 68) .. " " .. (x1 + 131) .. " 2 " .. (z1 + 131) .. " minecraft:air")
  629.             commands.execAsync("fill " .. (x1 - 4) .. " 0 " .. (z1 + 60) .. " " .. (x1 + 59) .. " 2 " .. (z1 + 131) .. " minecraft:air")
  630.            
  631.             -- Teleport pads:
  632.             commands.execAsync("fill " .. (x1 + 60) .. " 1 " .. (z1 + 60) .. " " ..(x1 + 61) .. " 1 " .. (z1 + 61) .. " minecraft:bedrock")
  633.             commands.execAsync("fill " .. (x1 + 66) .. " 1 " .. (z1 + 60) .. " " ..(x1 + 67) .. " 1 " .. (z1 + 61) .. " minecraft:bedrock")
  634.             commands.execAsync("fill " .. (x1 + 60) .. " 1 " .. (z1 + 66) .. " " ..(x1 + 61) .. " 1 " .. (z1 + 67) .. " minecraft:bedrock")
  635.             commands.execAsync("fill " .. (x1 + 66) .. " 1 " .. (z1 + 66) .. " " ..(x1 + 67) .. " 1 " .. (z1 + 67) .. " minecraft:bedrock")
  636.             commands.execAsync("setblock " .. (x1 + 61) .. " 2 " .. (z1 + 61) .. " minecraft:wooden_pressure_plate")
  637.             commands.execAsync("setblock " .. (x1 + 66) .. " 2 " .. (z1 + 61) .. " minecraft:wooden_pressure_plate")
  638.             commands.execAsync("setblock " .. (x1 + 61) .. " 2 " .. (z1 + 66) .. " minecraft:wooden_pressure_plate")
  639.             commands.execAsync("setblock " .. (x1 + 66) .. " 2 " .. (z1 + 66) .. " minecraft:wooden_pressure_plate")
  640.             commands.execAsync("setblock " .. (x1 + 61) .. " 0 " .. (z1 + 61) .. " minecraft:command_block 1 replace {Command:\"" .. teleport .. " @p " .. (x1 - 5) .. " 150 " .. (z1 - 5) .. "\"}")
  641.             commands.execAsync("setblock " .. (x1 + 66) .. " 0 " .. (z1 + 61) .. " minecraft:command_block 1 replace {Command:\"" .. teleport .. " @p " .. (x1 + 132) .. " 150 " .. (z1 - 5) .. "\"}")
  642.             commands.execAsync("setblock " .. (x1 + 61) .. " 0 " .. (z1 + 66) .. " minecraft:command_block 1 replace {Command:\"" .. teleport .. " @p " .. (x1 - 5) .. " 150 " .. (z1 + 132) .. "\"}")
  643.             commands.execAsync("setblock " .. (x1 + 66) .. " 0 " .. (z1 + 66) .. " minecraft:command_block 1 replace {Command:\"" .. teleport .. " @p " .. (x1 + 132) .. " 150 " .. (z1 + 132) .. "\"}")
  644.             commands.execAsync("setblock " .. (x1 + 60) .. " 2 " .. (z1 + 60) .. " minecraft:standing_sign 14 replace {Text2:\"{\\\"text\\\":\\\"North\\\"}\",Text3:\"{\\\"text\\\":\\\"West\\\"}\"}")
  645.             commands.execAsync("setblock " .. (x1 + 67) .. " 2 " .. (z1 + 60) .. " minecraft:standing_sign 2 replace {Text2:\"{\\\"text\\\":\\\"North\\\"}\",Text3:\"{\\\"text\\\":\\\"East\\\"}\"}")
  646.             commands.execAsync("setblock " .. (x1 + 60) .. " 2 " .. (z1 + 67) .. " minecraft:standing_sign 10 replace {Text2:\"{\\\"text\\\":\\\"South\\\"}\",Text3:\"{\\\"text\\\":\\\"West\\\"}\"}")
  647.             commands.execAsync("setblock " .. (x1 + 67) .. " 2 " .. (z1 + 67) .. " minecraft:standing_sign 6 replace {Text2:\"{\\\"text\\\":\\\"South\\\"}\",Text3:\"{\\\"text\\\":\\\"East\\\"}\"}")
  648.            
  649.             -- Swap computers (this will fail horribly if the original computer was already near bedrock):
  650.             commands.execAsync("setblock " .. (x1 + 64) .. " 1 " .. (z1 + 63) .. " computercraft:command_computer 3 replace {computerID:" .. os.getComputerID() .. ",x:" .. (x1 + 64) .. ",y:1,z:" .. (z1 + 63) .. ",id:\"computercraft : command_computer\",label:\"" .. os.getComputerLabel() .. "\",on:0b}")
  651.             commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:air")
  652.         end
  653.     elseif clickedAt(20, 31, 10) and ready then
  654.         -- Fill build area back in with featureless terrain.
  655.         clear(colours.black, colours.lightGrey)
  656.         term.setCursorPos(math.floor((xSize - 10) / 2) + 1, 5)
  657.         term.write("Filling...")
  658.         sleep(0)
  659.        
  660.         for y = 63, 255 do commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:air") end
  661.         commands.execAsync("fill " .. (x1 - 4) .. " 62 " .. (z1 - 4) .. " " .. (x1 + 131) .. " 62 " .. (z1 + 131) .. " minecraft:grass")
  662.         commands.execAsync("fill " .. (x1 - 4) .. " 0 " .. (z1 - 4) .. " " .. (x1 + 131) .. " 0 " .. (z1 + 131) .. " minecraft:bedrock")
  663.         for y = 56, 61 do commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:dirt") end
  664.         for y = 55, 3, -1 do commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:stone") end
  665.        
  666.         commands.execAsync("setblock " .. (x1 + 64) .. " 63 " .. (z1 + 63) .. " computercraft:command_computer 3 replace {computerID:" .. os.getComputerID() .. ",x:" .. (x1 + 64) .. ",y:63,z:" .. (z1 + 63) .. ",id:\"computercraft : command_computer\",label:\"" .. os.getComputerLabel() .. "\",on:0b}")
  667.         commands.execAsync(teleport .. " @p " .. (x1 + 64) .. " 64 " .. (z1 + 65))
  668.         for y = 2, 1, -1 do commands.execAsync("fill " .. (x1 - 4) .. " " .. y .. " " .. (z1 - 4) .. " " .. (x1 + 131) .. " " .. y .. " " .. (z1 + 131) .. " minecraft:stone") end
  669.     elseif clickedAt(20, 31, 12) or pressedKey(keys.q, keys.x) then
  670.         -- Exit.
  671.         if myEvent[1] == "key" then os.pullEvent("char") end
  672.         break
  673.     end
  674. end
  675.  
  676. ---------------------------------------------
  677. ------------         Exit        ------------
  678. ---------------------------------------------
  679.  
  680. term.setTextColour(colours.white)
  681. term.setBackgroundColour(colours.black)
  682. term.clear()
  683. term.setCursorPos(1, 1)
  684. print("Thanks for using mapArt!\n")
  685. shell.setDir(startDir)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement