BombBloke

partTerm (ComputerCraft)

May 21st, 2016
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.72 KB | None | 0 0
  1. -- +--------------------------------------------------------+
  2. -- |                                                        |
  3. -- |                     partTerm API                       |
  4. -- |                                                        |
  5. -- +--------------------------------------------------------+
  6.  
  7. local version = "Version 1.0.1"
  8.  
  9. -- By Jeffrey Alexander, aka Bomb Bloke.
  10. -- Draws pictures in the sky using the /particle command.
  11. -- Requires a Command Computer, plus ComputerCraft 1.76+ / Minecraft 1.8+.
  12. -- http://www.computercraft.info/forums2/index.php?/topic/26705-mc18-partterm-api/
  13.  
  14. -------------------------------------------------------------
  15.  
  16. local curCommands, maxCommands, tasks = 0, 50, {}
  17.  
  18. local colourChar, windows = {}, {}
  19.  
  20. local CCPal = {[0] = {240,240,240},{242,178, 51},{229,127,216},{153,178,242},
  21.         {222,222,108},{127,204, 25},{242,178,204},{ 76, 76, 76},
  22.         {153,153,153},{ 76,153,178},{178,102,229},{ 51,102,204},
  23.         {127,102, 76},{ 87,166, 78},{204, 76, 76},{ 25, 25, 25}}
  24.  
  25. do
  26.     local hex, temp1, temp2 = "0123456789abcdef", {}, {}
  27.    
  28.     for i = 1, 16 do
  29.         colourChar[2 ^ (i - 1)] = hex:sub(i, i)
  30.  
  31.         local thisPal = CCPal[i - 1]
  32.         temp1[hex:sub(i, i)] = " " .. tostring(thisPal[1] / 255 - 1) .. " " .. tostring(thisPal[2] / 255) .. " " .. tostring(thisPal[3] / 255) .. " 1"
  33.         temp2[hex:sub(i, i)] = " " .. tostring(thisPal[1] / 255) .. " " .. tostring(thisPal[2] / 255) .. " " .. tostring(thisPal[3] / 255) .. " 1"
  34.     end
  35.    
  36.     temp1["f"] = " -0.01 0 0 0.05"
  37.    
  38.     CCPal = {["reddust"] = temp1, ["mobSpell"] = temp2, ["mobSpellAmbient"] = temp2}
  39. end
  40.  
  41. local function snooze()
  42.     local myEvent = tostring({})
  43.     os.queueEvent(myEvent)
  44.     os.pullEvent(myEvent)
  45. end
  46.  
  47. local function doCommand(doThis)
  48.     while curCommands >= maxCommands do os.pullEvent("task_complete") end
  49.     tasks[commands.execAsync(doThis)] = true
  50.     curCommands = curCommands + 1
  51. end
  52.  
  53. local function rotatePoint(x, y, angle)
  54.     local sin, cos = math.sin(angle), math.cos(angle)
  55.     return x * cos - y * sin, x * sin + y * cos
  56. end
  57.  
  58. function getHorizontalAngle(x1, z1, x2, z2)
  59.     return math.deg(math.atan2(z2 - z1, x2 - x1)) -- + 90
  60. end
  61.  
  62. function getVerticalAngle(x1, y1, z1, x2, y2, z2)
  63.     return math.deg(math.atan2(math.sqrt((x2 - x1) ^ 2 + (z2 - z1) ^ 2), y2 - y1)) -- - 90
  64. end
  65.  
  66. function setDensity(commands)
  67.     if type(commands) ~= "number" then
  68.         error("partTerm.setDensity(): expected number")
  69.     elseif commands < 1 then
  70.         commands = 1
  71.     elseif commands > 250 then
  72.         commands = 250
  73.     end
  74.    
  75.     curCommands, maxCommands, tasks = 0, math.floor(commands), {}
  76. end
  77.  
  78. function remove(window)
  79.     windows[window] = nil
  80. end
  81.  
  82. function removeAll()
  83.     windows = {}
  84. end
  85.  
  86. function render()
  87.     parallel.waitForAny(
  88.         function()
  89.             while true do
  90.                 local event, id = os.pullEvent("task_complete")
  91.                 if tasks[id] then curCommands, tasks[id] = curCommands - 1, nil end
  92.             end
  93.         end,
  94.        
  95.         function()
  96.             while true do
  97.                 for window, values in pairs(windows) do
  98.                     local buffer, x, y, z, width, height, transCol, rotHori, rotVert, visible, spacing, bumps, partType = unpack(values)
  99.  
  100.                     if visible then
  101.                         local rowXBump, rowYBump, rowZBump, colXBump, colYBump, colZBump, offXBump, offYBump, offZBump = unpack(bumps)
  102.                         local yXBump, yYBump, yZBump, yy, pal = 0, 0, 0, 1, CCPal[partType]
  103.                         x, y, z = x + offXBump, y + offYBump, z + offZBump
  104.                        
  105.                         while yy <= height do
  106.                             local thisRow = buffer[yy]
  107.                            
  108.                             local xXBump, xYBump, xZBump = yXBump, yYBump, yZBump
  109.                            
  110.                             for xx = 1, width do
  111.                                 local thisChar = thisRow[xx]
  112.                                
  113.                                 if thisChar ~= transCol then
  114.                                     local curX, curY, curZ = x + xXBump, y + xYBump, z + xZBump
  115.                                     if math.floor(curX) == curX then curX = curX + 0.0001 end
  116.                                     if math.floor(curY) == curY then curY = curY + 0.0001 end
  117.                                     if math.floor(curZ) == curZ then curZ = curZ + 0.0001 end
  118.                                
  119.                                     doCommand("particle " .. partType .. " ".. curX .. " " .. curY .. " " .. curZ .. (pal and pal[thisChar] or " 0 0 0 1"))
  120.                                 end
  121.                                
  122.                                 xXBump, xYBump, xZBump = xXBump + rowXBump, xYBump + rowYBump, xZBump + rowZBump
  123.                             end
  124.                            
  125.                             yXBump, yYBump, yZBump, yy = yXBump + colXBump, yYBump + colYBump, yZBump + colZBump, yy + 1
  126.                         end
  127.                     end
  128.                    
  129.                     snooze()
  130.                 end
  131.             end
  132.         end
  133.        
  134.  
  135.     )
  136. end
  137.  
  138. function createWindow(x, y, z, width, height, transCol, rotHori, rotVert, visible, spacing, partType, center)
  139.     local buffer, window, tCol, bCol, curX, curY = {}, {}, colours.white, colours.black, 1, 1
  140.     local vals = {buffer, x, y, z, width, height, colourChar[transCol] or false, nil, nil, type(visible) ~= "boolean" and true or visible, spacing or 0.2, nil, partType or "reddust", type(center) ~= "boolean" and true or center}
  141.    
  142.     windows[window] = vals
  143.    
  144.     window.blit = function(_, _, bC)
  145.         local width, height = vals[5], vals[6]
  146.        
  147.         local bClen = #bC
  148.         if curX > width or curX + bClen < 2 or curY < 1 or curY > height then
  149.             curX = curX + bClen
  150.             return
  151.         end
  152.        
  153.         if curX < 1 then
  154.             bC = bC:sub(2 - curX)
  155.             curX, bClen = 1, #bC
  156.         end
  157.        
  158.         if curX + bClen - 1 > width then bC, bClen = bC:sub(1, width - curX + 1), width - curX + 1 end
  159.  
  160.         local row = buffer[curY]
  161.         for x = 1, bClen do row[x + curX - 1] = bC:sub(x, x) end
  162.        
  163.         curX = curX + bClen
  164.     end
  165.    
  166.     window.write = function(text)
  167.         window.blit(nil, nil, string.rep(colourChar[bCol], #tostring(text)))
  168.     end
  169.    
  170.     window.clearLine = function()
  171.         local colChar, row = colourChar[bCol], buffer[curY]
  172.         for x = 1, vals[5] do row[x] = colChar end
  173.     end
  174.    
  175.     window.clear = function()
  176.         local colChar, width = colourChar[bCol], vals[5]
  177.        
  178.         for y = 1, vals[6] do
  179.             local row = {}
  180.             for x = 1, width do row[x] = colChar end
  181.             buffer[y] = row
  182.         end
  183.     end
  184.    
  185.     window.getCursorPos = function()
  186.         return curX, curY
  187.     end
  188.    
  189.     window.setCursorPos = function(newX, newY)
  190.         curX, curY = math.floor(newX), math.floor(newY)
  191.     end
  192.    
  193.     window.setCursorBlink = function() end
  194.    
  195.     window.isColour = function()
  196.         return true
  197.     end
  198.     window.isColor = window.isColour
  199.    
  200.     window.getSize = function()
  201.         return vals[5], vals[6]
  202.     end
  203.    
  204.     window.scroll = function(lines)
  205.         lines = math.floor(lines)
  206.        
  207.         if lines ~= 0 then
  208.             local newBuff, colChar, width, height = {}, colourChar[bCol], vals[5], vals[6]
  209.            
  210.             for i = 1, height do
  211.                 if i + lines > 0 and i + lines <= height then
  212.                     newBuff[i] = buffer[i + lines]
  213.                 else
  214.                     local row = {}
  215.                     for x = 1, width do row[x] = colChar end
  216.                     newBuff[i] = row
  217.                 end
  218.             end
  219.            
  220.             buffer, vals[1] = newBuff, newBuff
  221.         end
  222.     end
  223.    
  224.     window.setTextColour = function(newCol)
  225.         tCol = newCol
  226.     end
  227.     window.setTextColor = window.setTextColour
  228.    
  229.     window.setBackgroundColour = function(newCol)
  230.         bCol = newCol
  231.     end
  232.     window.setBackgroundColor = window.setBackgroundColour
  233.    
  234.     window.getTextColour = function()
  235.         return tCol
  236.     end
  237.     window.getTextColor = window.getTextColour
  238.    
  239.     window.getBackgroundColour = function()
  240.         return bCol
  241.     end
  242.     window.getBackgroundColor = window.getBackgroundColour
  243.    
  244.     window.setVisible = function(newVis)
  245.         vals[10] = newVis and true or false
  246.     end
  247.    
  248.     window.setSpacing = function(newSpacing)
  249.         vals[11] = newSpacing
  250.         window.setAngles(window.getAngles())
  251.     end
  252.    
  253.     window.getPosition = function()
  254.         return vals[2], vals[3], vals[4]
  255.     end
  256.    
  257.     window.getAngles = function()
  258.         return vals[8], vals[9]
  259.     end
  260.    
  261.     window.setParticle = function(newPart)
  262.         vals[13] = newPart
  263.     end
  264.    
  265.     window.center = function(center)
  266.         vals[14] = type(center) ~= "boolean" and true or center
  267.         window.setAngles(window.getAngles())
  268.     end
  269.    
  270.     window.reposition = function(newX, newY, newZ, newWidth, newHeight)
  271.         if type(newX) == "number" then vals[2] = newX end
  272.         if type(newY) == "number" then vals[3] = newY end
  273.         if type(newZ) == "number" then vals[4] = newZ end
  274.        
  275.         if newWidth or newHeight then
  276.             local oldW, oldH, colChar = vals[5], vals[6], colourChar[bCol]
  277.             if not newWidth then newWidth = oldW end
  278.             if not newHeight then newHeight = oldH end
  279.            
  280.             local newBuff = {}
  281.            
  282.             for y = 1, newHeight do
  283.                 local row = {}
  284.                
  285.                 if y <= oldH then
  286.                     local oldRow = buffer[y]
  287.                     for x = 1, newWidth do row[x] = oldRow[x] or colChar end
  288.                 else
  289.                     for x = 1, newWidth do row[x] = colChar end
  290.                 end
  291.                
  292.                 newBuff[y] = row
  293.             end
  294.            
  295.             buffer, vals[1], vals[5], vals[6] = newBuff, newBuff, newWidth, newHeight
  296.            
  297.             window.setAngles(window.getAngles())
  298.         end
  299.     end
  300.    
  301.     window.setAngles = function(rotHori, rotVert)
  302.         if type(rotHori) == "number" then
  303.             rotHori = math.rad(rotHori + 180)
  304.             vals[8] = rotHori
  305.         else rotHori = vals[8] end
  306.        
  307.         if type(rotVert) == "number" then
  308.             rotVert = math.rad(rotVert)
  309.             vals[9] = rotVert
  310.         else rotVert = vals[9] end
  311.        
  312.         local spacing = vals[11]
  313.        
  314.         local rowXBump, rowYBump, rowZBump
  315.         rowZBump, rowYBump = rotatePoint(0, 0, rotVert)
  316.         rowXBump, rowZBump = rotatePoint(1, rowZBump, rotHori)
  317.         rowXBump, rowYBump, rowZBump = rowXBump * spacing, -(rowYBump * spacing), rowZBump * spacing
  318.  
  319.         local colXBump, colYBump, colZBump
  320.         colZBump, colYBump = rotatePoint(0, 1, rotVert)
  321.         colXBump, colZBump = rotatePoint(0, colZBump, rotHori)
  322.         colXBump, colYBump, colZBump = colXBump * spacing, -(colYBump * spacing), colZBump * spacing
  323.        
  324.         local offXBump, offYBump, offZBump
  325.         if vals[14] then
  326.             local width, height = -(vals[5] / 2), -(vals[6] / 2)
  327.             offXBump, offYBump, offZBump = rowXBump * width + colXBump * height, rowYBump * width + colYBump * height, rowZBump * width + colZBump * height
  328.         else offXBump, offYBump, offZBump = 0, 0, 0 end
  329.        
  330.         vals[12] = {rowXBump, rowYBump, rowZBump, colXBump, colYBump, colZBump, offXBump, offYBump, offZBump}
  331.     end
  332.    
  333.     window.setAngles(rotHori or 0, rotVert or 0)
  334.     window.clear()
  335.     return window
  336. end
Add Comment
Please, Sign In to add comment