FartNebuleuse

Epic visualizer

Jun 23rd, 2021 (edited)
233
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --@name Epic visualizer
  2. --@author NekerSqu4w
  3. //version 2.18 Please don't delete this line to have auto update :D
  4. --@include ./playlist.txt
  5. --@include ./lang.txt
  6. --@include ./color.txt
  7.  
  8. //Changelog 2.17
  9. //
  10. // Added a visible cursor.
  11. // Possibility to choose between radio, mp3, or youtube.
  12. // Added more color palettes.
  13. // Playlist, lang, color removed from the code to replace it by a include.
  14. //
  15.  
  16. //Changelog 2.18
  17. //
  18. // mp3 now support streamed file
  19. //
  20.  
  21. if SERVER then
  22.    -- Auto link screen
  23.    if chip():isWeldedTo() then
  24.        chip():isWeldedTo():linkComponent(chip())
  25.    end
  26.    -------------------------------------------------------
  27. end
  28.  
  29. if CLIENT then
  30.    -- Important information (Before run the code for the first time)
  31.    //Download the playlist here --> 'https://pastebin.com/QsGfs7sZ'
  32.    //Download the lang file here --> 'https://pastebin.com/pTkL06UW'
  33.    //Download the color palettes file here --> 'https://pastebin.com/n8fgDFww'
  34.    
  35.    //If the chip crash, write 'sf_timebuffer_cl_owner 0.050000' in the console.
  36.  
  37.    -- Settings
  38.    //TODO: Make my own YouTube to MP3 api.
  39.  
  40.    local track = 91
  41.    local list = "mp3" //radio, mp3, youtube(Doesn't work for the moment.)
  42.     local lang_use = "EN_lang"
  43.     local principal_color = Color(255,75,75)
  44.    
  45.     local volume = 0.5
  46.     local max_hearing_distance = 1000
  47.     -------------------------------------------------------
  48.  
  49.     -- Variable
  50.     local playlist = require("./playlist.txt")
  51.     local lang = require("./lang.txt")(lang_use)
  52.     local color = require("./color.txt")
  53.     local bassfft, snd_data = 0, nil
  54.     local shake1, shake2 = 0, 0
  55.     local fft, smooth_fft, visualizer = {}, {}, {}
  56.     local startup = 1
  57.     local black, black2 = 0, 0
  58.     local startUpSize = 1300
  59.     local posRight = 0
  60.     local r,g,b,r2,g2,b2,r3,g3,b3 = 0,0,0,{},{},{},0,0,0
  61.     local time, duration = 0, 10
  62.     local color_menu, show_visualizer = false, true
  63.     local sizeToX, sizeToY = 0, 0
  64.     local sizeX, sizeY = 0, 0
  65.     local pi2 = math.pi*2
  66.     local loading = ""
  67.     local mat = {}
  68.     local b_size = Vector(1280,720)
  69.     if list == "mp3" or list == "radio" then b_size = Vector(1024,1024) end
  70.     local looping = true
  71.     local use_color = 1
  72.     local click_possible = false
  73.    
  74.     local fontName = "Akbar"
  75.     local font = render.createFont(fontName, 250+50, 250+50, true, false, false, false, false, true)
  76.     local font2 = render.createFont(fontName, 120+50, 120+50, true, false, false, false, false, true)
  77.     local font3 = render.createFont(fontName, 180+50, 180+50, true, false, false, false, false, true)
  78.  
  79.     local last_max = 0
  80.     local bc = 1
  81.     local si = {}
  82.     local ra = {}
  83.                
  84.     for i=1, 30 do
  85.         ra[i] = 512
  86.         si[i] = 1
  87.     end
  88.    
  89.     local Light = light.create(chip():getPos(),700,5,Color(0,0,0))
  90.  
  91.     local URL = playlist[list][track].link or ""
  92.     local Name = playlist[list][track].title or ""
  93.     local background = playlist[list][track].background or "https://i.imgur.com/trTUlBW.png?1"
  94.    
  95.     for i=1, 7 do mat[i] = material.create("UnlitGeneric") end
  96.    
  97.     render.createRenderTarget("visualizer")
  98.     render.createRenderTarget("background")
  99.    
  100.     visualizer["1"] = { {x = 256, y = 256} }
  101.     visualizer["2"] = { {x = 256, y = 256} }
  102.     for i = 2, 50 + 1 do for v = 1, 1 do visualizer["1"][i] = {} visualizer["2"][i] = {} end end
  103.    
  104.     -------------------------------------------------------
  105.    
  106.     -- Custom function  
  107.     local cursor = {
  108.         { x=0, y=0 },
  109.         { x=3, y=2 },
  110.         { x=1.1, y=2 },
  111.         { x=2.1, y=3.9 },
  112.         { x=1.9, y=4 },
  113.         { x=0.9, y=2.1 },
  114.         { x=0.1, y=4 },
  115.     }
  116.    
  117.     function getMouse(curX, curY, scale)
  118.         local copyMouse = table.copy(cursor)
  119.        
  120.         for i=1, #copyMouse do
  121.             copyMouse[i].x = copyMouse[i].x*scale + curX
  122.             copyMouse[i].y = copyMouse[i].y*scale + curY
  123.         end
  124.         return copyMouse
  125.     end
  126.    
  127.     function drawMouse(curX, curY)
  128.         render.setRenderTargetTexture()
  129.    
  130.         copyMouse = getMouse(curX, curY, 4)
  131.         render.drawPoly(copyMouse)
  132.     end
  133.    
  134.     local function quotaCheck(n)
  135.         return math.max(quotaAverage(), quotaUsed()) < quotaMax() * n
  136.     end
  137.    
  138.     local num = nil
  139.     function changed(value)
  140.         if not num == value then num = value val = true else val = false end
  141.         return val
  142.     end
  143.    
  144.     local bassVal = 0
  145.     function getBass(ft,limit)
  146.         for h=1, limit do
  147.             for w=1, limit do
  148.                 if (ft[h] or 0) < (ft[w] or 0) then
  149.                     bassVal = math.lerp(0.1/200,bassVal,(ft[w] or 0)*10)
  150.                 elseif (ft[h] or 0) > (ft[w] or 0) then
  151.                     bassVal = math.lerp(0.1/200,bassVal,(ft[h] or 0)*10)
  152.                 end
  153.             end
  154.         end
  155.        
  156.         return bassVal
  157.     end
  158.    
  159.     local val = 0
  160.     local a = {}
  161.     function getMaxFft(ft,limit)
  162.         for h=1, limit do a[h] = 0 end
  163.        
  164.         for h=1, limit do
  165.             val = math.max((ft[h] or a[h]))
  166.         end
  167.         return val
  168.     end
  169.  
  170.     function fftToRadius(i) return 54 + bassfft*20 - math.log10(i) - (smooth_fft[50-i] or 0)*100 end
  171.    
  172.     function inrange(x, y, w, h)
  173.         local cx, cy = render.cursorPos()
  174.         if not cx or not cy then return false end
  175.      
  176.         if cx > x and cx < x+w then
  177.             if cy > y and cy < y+h then
  178.                 return true
  179.             end
  180.         end
  181.     end
  182.    
  183.     function information(cx,cy,txt,res,use_font)
  184.         render.setFont(use_font)
  185.         local w,h = render.getTextSize(txt)
  186.        
  187.         render.setColor(Color(0,0,0,100))
  188.         render.drawRect((cx/512)*res+50, (cy/512)*res-80, w, h)
  189.        
  190.         render.setColor(Color(255,255,255))
  191.         render.drawText((cx/512)*res+50, (cy/512)*res-85, txt,0)
  192.        
  193.         return (w/res)*512,(h/res)*512
  194.     end
  195.    
  196.     -------------------------------------------------------
  197.  
  198.     -- Slider function
  199.     local Slider = class("Slider")
  200.     local objects = {}
  201.  
  202.     function Slider:initialize(x, y, w, h, min, max, val, round, info, show_title, can_change)
  203.         self.x = x
  204.         self.y = y
  205.         self.w = w
  206.         self.h = h
  207.         self.min = min or 0
  208.         self.max = max or 100
  209.         self.val = val or 0
  210.         self.round = round or 0
  211.         self.info = info or ""
  212.         self.normal = self.val or 0
  213.         self.title = show_title or false
  214.         self.can_change = can_change or false
  215.  
  216.         self.color1 = Color(100,100,100)
  217.         self.color2 = Color(100,130,255)
  218.         self.color3 = Color(230,230,230)
  219.  
  220.         table.insert(objects, self)
  221.     end
  222.  
  223.     function Slider:think()
  224.         if self.active then
  225.  
  226.             local cx, cy = render.cursorPos()
  227.             if not cx or not cy then return end
  228.  
  229.             cx = math.clamp(cx, self.x, self.x + self.w)
  230.             self.val = self.max / self.w * (cx - self.x)
  231.  
  232.         end
  233.  
  234.         if self.customThink then self:customThink() end
  235.     end
  236.  
  237.     function Slider:paint()
  238.         local m = Matrix()
  239.         m:setScale(Vector(0.08))
  240.         render.pushMatrix(m)
  241.  
  242.         local v = self.w / self.max * self.val
  243.  
  244.         render.setColor(self.color1/1.3)
  245.         render.drawRect((self.x/512)*6400, ((self.y+self.h/2.6)/512)*6400, (self.w/512)*6400, ( (self.h/4 )/512)*6400)
  246.  
  247.         render.setColor(self.color2)
  248.         render.drawRect((self.x/512)*6400, ((self.y+self.h/2.6)/512)*6400, (v/512)*6400, ( (self.h/4 )/512)*6400)
  249.  
  250.         if self.active then
  251.             render.setColor((self.color2/1.3):setA(255))
  252.         else
  253.             render.setColor(self.color2)
  254.         end
  255.  
  256.         render.drawRoundedBox( 1000, ((self.x+v - (self.h/3) )/512)*6400,((self.y+self.h/6)/512)*6400, ( (self.h/1.5)/512)*6400, ( (self.h/1.5)/512)*6400 )
  257.  
  258.         if self.active and self.title then
  259.             render.setFont(render.createFont("akbar", 200, 200, true, false, false, false, false, false))
  260.             local width, height = render.getTextSize( math.round(self.val,self.round) .. " (" .. tostring(math.round((self.val/1)*100)) .. self.info .. ")" )
  261.  
  262.             render.setColor(self.color3)
  263.             render.setMaterial()
  264.             render.drawRect(((self.x + v)/512)*6400 - (width+50)/2,((self.y-10)/512)*6400 - height/2,width+50,height)
  265.  
  266.             render.setColor(Color(255,255,255))
  267.             render.setFont(render.createFont("akbar", 200, 200, true, false, false, false, false, false))
  268.             render.drawSimpleText(((self.x + v)/512)*6400, ((self.y-10)/512)*6400, math.round(self.val,self.round) .. " (" .. tostring(math.round((self.val/1)*100)) .. self.info .. ")", 1, 1)
  269.         end
  270.  
  271.         render.popMatrix()
  272.     end
  273.    
  274.     function markElement(active)
  275.  
  276.         if not active then
  277.             -- disable all elements
  278.  
  279.             for k, v in pairs(objects) do
  280.                 v.active = false
  281.             end
  282.  
  283.         else
  284.             -- find element under cursor
  285.             for k, v in pairs(objects) do
  286.                 if inrange(v.x, v.y, v.w, v.h) then
  287.                     v.active = true
  288.                     break
  289.                 end
  290.             end
  291.  
  292.         end
  293.  
  294.     end
  295.     -------------------------------------------------------
  296.    
  297.     -- Particle function
  298.     local Particle = class("Particle")
  299.     function Particle:initialize(pos, scale, direction, clr)
  300.         self.x = pos.x or 0
  301.         self.y = pos.y or 0
  302.         self.scale = scale or 0
  303.         self.x_vel = direction.x or 0
  304.         self.y_vel = direction.y or 0
  305.         self.color = clr:setA(255) or Color(0, 0, 0, 255)
  306.     end
  307.    
  308.     function Particle:think()
  309.         self:draw()
  310.    
  311.         self.x = self.x + self.x_vel
  312.         self.y = self.y + self.y_vel
  313.    
  314.         self.scale = self.scale - math.random(0.20, 0.30)
  315.     end
  316.    
  317.     function Particle:draw()
  318.         render.setColor(self.color:setA(255))
  319.         render.setMaterial(mat[3])
  320.         render.drawTexturedRect(self.x - self.scale/2, self.y - self.scale/2, self.scale, self.scale)
  321.         render.setMaterial(nil)
  322.         render.setColor(Color(255,255,255):setA(255))
  323.     end
  324.    
  325.     local game = {}
  326.     game.particles = {}
  327.    
  328.     -------------------------------------------------------
  329.  
  330.     -- Show the visualizer
  331.     function load()
  332.         bass.loadURL(URL,"noblock",function(snd)
  333.             -- Setup slider
  334.             timer.create("Setup",1,1,function()
  335.                 local volume_slider = Slider(400-150/2, 480-20/2, 150, 20, 0, 2, volume, 2, "%", true, false)
  336.                 volume_slider.customThink = function(self)
  337.                     self.color1 = Color(150, 150, 150):setA(75)
  338.                     self.color2 = principal_color
  339.                     self.color3 = Color(0,0,0,150)
  340.              
  341.                     volume = 2 / self.max * self.val
  342.                 end
  343.                
  344.                 if snd:isOnline() then else
  345.                     local time_slider = Slider(20, 496, 472, 12, time, duration, 0, 0, "", false, true)
  346.                     time_slider.customThink = function(self)
  347.                         self.color1 = Color(150, 150, 150):setA(75)
  348.                         self.color2 = principal_color
  349.                         self.color3 = Color(0,0,0,150)
  350.                        
  351.                         snd_data:setTime(self.val)
  352.                     end
  353.                     time_slider:think()
  354.                 end
  355.                
  356.                 snd_data:play()
  357.             end)
  358.             -------------------------------------------------------
  359.        
  360.             snd:pause()
  361.             hook.add("render","",function()
  362.                 if snd:isValid() then
  363.                     snd_data = snd
  364.                     snd:setPos(render.getScreenEntity():getPos())
  365.                     if snd:isOnline() then else snd:setLooping(looping) end
  366.  
  367.                     local dist = player():getPos():getDistance(chip():getPos())
  368.                     if dist > max_hearing_distance then snd:setVolume(0) else snd:setVolume(volume - (dist/max_hearing_distance)*volume) end
  369.  
  370.                     fft = snd:getFFT(4)
  371.                     duration = snd:getLength()
  372.                     time = snd:getTime()
  373.                    
  374.                     if startup == 10 then
  375.                         bassfft = getBass(fft,20)
  376.                     end
  377.                 end
  378.  
  379.                 local cx, cy = render.cursorPos()
  380.                 click_possible = false
  381.  
  382.                 shake1 = math.lerp(0.2,shake1,math.random(-bassfft*7,bassfft*7))
  383.                 shake2 = math.lerp(0.2,shake2,math.random(-bassfft*7,bassfft*7))
  384.  
  385.                 local real = color[use_color].color[1] or Color(0,0,0)
  386.                 r = math.lerp(0.2,r, real.r)
  387.                 g = math.lerp(0.2,g, real.g)
  388.                 b = math.lerp(0.2,b, real.b)
  389.            
  390.                 Light:draw()
  391.                 Light:setPos( render.getScreenEntity():getPos() )
  392.                 Light:setColor(Color(r,g,b)*bassfft)
  393.  
  394.                 -- Background  
  395.                 render.selectRenderTarget("background")
  396.  
  397.                 render.setCullMode(1)    
  398.                 render.setMaterial(mat[1])
  399.                 render.setColor(Color(0, 0, 1):hsvToRGB())
  400.                 render.drawTexturedRect( 256, 0, -750 - (1280-math.clamp(b_size.x,0,1280)), 750 + (720-math.clamp(b_size.y,0,720)))
  401.                
  402.                 render.setCullMode(0)
  403.                 render.drawTexturedRect( 256, 0, 750 + (1280-math.clamp(b_size.x,0,1280)), 750 + (720-math.clamp(b_size.y,0,720)))
  404.  
  405.                 if startup == 5 then
  406.                     render.capturePixels()
  407.                     for i=1, 10 do
  408.                         real = render.readPixel(-(0.5/10)*512 + (i/10)*512,-(0.5/10)*512 + (i/10)*512)
  409.                         color[1].color[i] = real
  410.                     end
  411.                 end
  412.  
  413.                 render.setMaterial(nil)
  414.                 render.selectRenderTarget(nil)
  415.                
  416.                
  417.                 render.setColor(Color(0, 0, black+bassfft/4):hsvToRGB())
  418.                 render.setRenderTargetTexture("background")
  419.                 render.drawTexturedRect(0-bassfft/4*20,0-bassfft/4*20,1024+bassfft*20,1024+bassfft*20)
  420.                
  421.                 -------------------------------------------------------
  422.                
  423.                 if startup == 10 and show_visualizer == true then
  424.                     -- Setup and draw Particle
  425.                     if #game.particles <= 100 then
  426.                         local nP = Particle:new(Vector(256,256),math.random(20, 50)*(0.5+bassfft/2),Vector(math.random(-3,3)*(0.5+bassfft*4),math.random(-3,3)*(0.5+bassfft*4)),color[use_color].color[math.random(1,#color[use_color].color)])
  427.                         table.insert(game.particles, nP)
  428.                     end
  429.                            
  430.                     for k, v in pairs(game.particles) do
  431.                         if v.scale <= 0 then table.remove(game.particles, k) continue end
  432.                            
  433.                         v.x_vel = v.x_vel - (0 * (1 / 2000) * (40 / v.scale))
  434.                         v.y_vel = v.y_vel - (0 * (1 / 2000) * (40 / v.scale))
  435.                            
  436.                         v:think()
  437.                     end
  438.                
  439.                 -------------------------------------------------------
  440.                
  441.                     -- Setup visualizer
  442.                     for i=2, 50+1 do
  443.                         local theta = (((i - 1) - 1) * math.pi / (50 - 1))
  444.                         smooth_fft[i] = math.lerp((0.1*7.5),(smooth_fft[i] or 0), (fft[50+2-i+1] or 0) )
  445.                        
  446.                         for v=1, 1 do
  447.                             visualizer["1"][i].x = 256 + shake1 + math.cos(math.pi/2+theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
  448.                             visualizer["1"][i].y = 256 + shake2 + math.sin(math.pi/2+theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
  449.                            
  450.                             visualizer["2"][i].x = 256 + shake1 + math.cos(math.pi/2-theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
  451.                             visualizer["2"][i].y = 256 + shake2 + math.sin(math.pi/2-theta + timer.curtime()/4) * (58 + ((smooth_fft[50+2-i + 1] or 0) * 140) + (bassfft * 20) + 50/4)
  452.                         end
  453.                     end
  454.  
  455.                     -------------------------------------------------------
  456.                
  457.                     -- Draw visualizer
  458.                     render.selectRenderTarget("visualizer")
  459.                    
  460.                     render.setMaterial(nil)
  461.                     render.clear(Color(0,0,0,0))
  462.                    
  463.                     render.setColor(Color(255, 255, 255))
  464.                     render.setCullMode(0)
  465.                     render.drawPoly(visualizer["1"])
  466.                     render.setCullMode(1)
  467.                     render.drawPoly(visualizer["2"])
  468.                    
  469.                     render.setCullMode(0)
  470.  
  471.                     render.selectRenderTarget(nil)
  472.  
  473.                     for v=1, #color[use_color].color do
  474.                         local real = color[use_color].color[math.round(#color[use_color].color+1-v)] or Color(0,0,0)
  475.                         r2[v] = math.lerp(0.2,r2[v] or 0, real.r)
  476.                         g2[v] = math.lerp(0.2,g2[v] or 0, real.g)
  477.                         b2[v] = math.lerp(0.2,b2[v] or 0, real.b)
  478.                         render.setColor(Color(r2[v],g2[v],b2[v]):setA(255))
  479.  
  480.                         render.setRenderTargetTexture("visualizer")
  481.                         render.drawTexturedRect(-200/4 + (v/#color[use_color].color)*200/4,-200/4 + (v/#color[use_color].color)*200/4,1024+200 - (v/#color[use_color].color)*200,1024+200 - (v/#color[use_color].color)*200)
  482.                     end
  483.                 end
  484.                
  485.                 -------------------------------------------------------
  486.                
  487.                 -- Starting animation
  488.                 if startup == 1 then if startUpSize >= -50 then startUpSize = startUpSize - 2 - (startUpSize/1300)*30 end end
  489.                 if startUpSize <= 100 and startup == 1 then if posRight <= 180 then posRight = posRight + 1 + (posRight/180)*2 black = (posRight/180)*0.2 else startup = 3 end end
  490.                 if startup == 3 then timer.create("aaaaa",2,1,function() startup = 5 end) startup = 4 end
  491.                 if startup == 5 then if posRight >= 0 then posRight = posRight - 5 black = 0.4-(posRight/180)*0.2 black2 = 1-(posRight/180)*1 end end
  492.                 if startup == 5 then if startUpSize <= 50 then startUpSize = startUpSize + 3 - (startUpSize/50)*2.9 else startup = 10 end end
  493.  
  494.                 if startup == 2 or startup == 3 or startup == 4 or startup == 5 or startUpSize <= 5 then
  495.                     render.setMaterial(mat[2])
  496.  
  497.                     render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*600,0,255)))
  498.                     render.drawTexturedRect(256 - 70/4 + posRight*1.2, 256 - 70/4, 70, 70)            
  499.                     render.drawTexturedRect(256 - 70/4 - posRight*1.2, 256 - 70/4, 70, 70)
  500.  
  501.                     render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*1000,0,255)))
  502.                     render.drawTexturedRect(256 - 110/4 - posRight/1.1, 256 - 110/4, 110, 110)
  503.                     render.drawTexturedRect(256 - 110/4 + posRight/1.1, 256 - 110/4, 110, 110)
  504.  
  505.                     render.setColor(Color(255, 255, 255):setA(math.clamp( 255-black2*1400,0,255)))
  506.                     render.drawTexturedRect(256 - 140/4 - posRight/2, 256 - 140/4, 140, 140)
  507.                     render.drawTexturedRect(256 - 140/4 + posRight/2, 256 - 140/4, 140, 140)
  508.                    
  509.                     render.setMaterial(nil)
  510.                 end
  511.                
  512.                 -------------------------------------------------------
  513.                
  514.                 -- Draw punch circle
  515.                 if startup == 10 and show_visualizer == true then
  516.                     if getMaxFft(fft,5) - last_max > 0.2 then
  517.                         bc = bc + 1
  518.                         bc = bc % 30
  519.                    
  520.                         si[bc] = 1 + getMaxFft(fft,5)*10
  521.                         ra[bc] = 50
  522.                     end
  523.                    
  524.                     last_max = getMaxFft(fft,5)/2
  525.    
  526.                     for i=1, 30 do
  527.                         if ra[i] < 512 then ra[i] = ra[i] + si[i] end
  528.                         render.setColor(color[use_color].color[1]:setA(255-(ra[i]/512)*255))
  529.                         render.drawCircle(256,256,ra[i])
  530.                     end
  531.                 end
  532.  
  533.                 -------------------------------------------------------
  534.                
  535.                 if show_visualizer == true then
  536.                     -- Logo
  537.                     render.setMaterial(mat[2])
  538.                     render.setColor(Color(255, 255, 255))
  539.                     render.drawTexturedRect(512/2 - 220/4 - bassfft*80*0.25 + shake1 - startUpSize/4, 512/2 - 220/4 - bassfft*80*0.25 + shake2 - startUpSize/4, 220 + bassfft*80 + startUpSize, 220 + bassfft*80 + startUpSize)
  540.  
  541.                     -------------------------------------------------------
  542.                 end
  543.                
  544.                 -- Visualizer in logo
  545.                 if startup == 10 and show_visualizer == true then
  546.                     render.setMaterial(nil)
  547.                     r3,g3,b3 = color[use_color].color[1].r,color[use_color].color[1].g,color[use_color].color[1].b
  548.                    
  549.                     for i=1, 29 do
  550.                         local theta = (i-1)*2*(math.pi/2.5)/(30-1)
  551.  
  552.                         local real = color[use_color].color[math.round(#color[use_color].color * (i/29))] or Color(0,0,0)
  553.                         r3 = math.lerp(0.5,r3, real.r)
  554.                         g3 = math.lerp(0.5,g3, real.g)
  555.                         b3 = math.lerp(0.5,b3, real.b)
  556.  
  557.                         render.setColor(Color(r3, g3, b3, 150))
  558.                         render.drawTexturedRectRotated( 256 + shake1 + math.sin(-math.pi/2.5+theta) * fftToRadius(i), 256 + shake2 + math.cos(-math.pi/2.5+theta) * fftToRadius(i), 4, 2 + (smooth_fft[50-i] or 0)*200, -360/3.3+(360/2.5)/29+i*-(360/2.5)/29)
  559.                     end
  560.                    
  561.                     -------------------------------------------------------
  562.                 end
  563.                
  564.                 if startup == 10 then
  565.                     local m = Matrix()
  566.                     m:setScale(Vector(0.08))
  567.                     render.pushMatrix(m)
  568.                        
  569.                     -- Time bar
  570.                     render.setColor(principal_color)
  571.                     if snd:isOnline() then
  572.                         render.drawRoundedBox(0, (6400-5900)/2 , 6200, 5900, 40)
  573.                     end
  574.  
  575.                     if snd:isOnline() then
  576.                         render.setColor(Color(255))
  577.                         render.setFont(font3)
  578.                         render.drawSimpleText(800, 6000, lang.live.."",1,1)
  579.  
  580.                         render.setColor(principal_color)
  581.                         render.drawRoundedBox( 1000, 450-70/2, 6010-70/2, 70, 70 )
  582.                     else
  583.                         render.setColor(Color(255))
  584.                         render.setFont(font3)
  585.                         render.setFilterMag(1)
  586.  
  587.                         render.drawSimpleText(600, 6000, string.toMinutesSeconds(time),1,1)
  588.                        
  589.                         render.setColor(Color(120,120,120))
  590.                         render.drawSimpleText(1100, 6000,"/" .. string.toMinutesSeconds(duration),1,1)
  591.                     end
  592.                    
  593.                     render.setColor(Color(120,120,120))
  594.                     render.setFont(font)
  595.                     render.drawSimpleText(200, 200, "" .. track,1,1)
  596.  
  597.                     render.setColor(Color(255))
  598.                     render.setFont(font)
  599.                     render.drawSimpleText(400, 150, "" .. Name,0,1)
  600.  
  601.                     render.setColor(Color(180,180,180))
  602.                     render.setFont(font2)
  603.                     render.drawSimpleText(400, 320, "" .. playlist[list][track].link,0,1)
  604.                    
  605.                     sizeX = math.lerp(0.4,sizeX,sizeToX)
  606.  
  607.                     render.setColor(Color(0, 0, 0, 255))
  608.                     render.setMaterial(mat[4])
  609.                     render.drawTexturedRect(0,0,6400,450)
  610.  
  611.                     render.setColor(Color(0, 0, 0, 255))
  612.                     render.setMaterial(mat[5])
  613.                     render.drawTexturedRect(0, 5800, 6400, 600)
  614.  
  615.                     render.setColor(Color(0, 0, 0, 255))
  616.                     render.setMaterial(mat[6])
  617.                     render.drawTexturedRect(0, 0, 0 + sizeX, 6400)
  618.  
  619.                     render.setColor(Color(0, 0, 0, 75))
  620.                     render.drawRect(sizeX/2, 500, 300, 300)
  621.                    
  622.                     ------------------------------------------------
  623.  
  624.                     if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
  625.                         click_possible = true
  626.                         if color_menu == true then
  627.                             information(cx+4,cy+23,lang.color_on.."",6400,font3)
  628.                         else
  629.                             information(cx+4,cy+23,lang.color_off.."",6400,font3)
  630.                         end
  631.                     end
  632.  
  633.                     if color_menu == true and not snd:isOnline() or color_menu == true and not snd:isOnline() then
  634.                         render.setColor(Color(255,255,255))
  635.                         render.setFont(font3)
  636.  
  637.                         if looping == true then
  638.                             render.drawSimpleText(sizeX/2-100, 1300 + #color*180, lang.loop_on.."",0,1)
  639.                         else
  640.                             render.drawSimpleText(sizeX/2-100, 1300 + #color*180, lang.loop_off.."",0,1)
  641.                         end
  642.                     end
  643.  
  644.                     if color_menu == true then
  645.                         render.setColor(Color(255,255,255))
  646.                         render.setFont(font3)
  647.                         if show_visualizer == true then
  648.                             render.drawSimpleText(sizeX/2-100, 1600 + #color*180, lang.visualizer_on.."",0,1)
  649.                         else
  650.                             render.drawSimpleText(sizeX/2-100, 1600 + #color*180, lang.visualizer_off.."",0,1)
  651.                         end
  652.                        
  653.                         sizeToX = 1500
  654.  
  655.                         render.setColor(Color(255, 255, 255))
  656.                         render.setMaterial(mat[7])
  657.                         render.drawTexturedRectRotated(sizeX/2+190, 500+150, 300, 300,-45)
  658.  
  659.                         for i=1, #color do
  660.                             if use_color == i then
  661.                                 render.setColor(Color(255, 255, 255))
  662.                                 render.setMaterial(mat[7])
  663.                                 render.drawTexturedRectRotated(sizeX/2, 750 + i*180, 150, 150,-45)
  664.                             end
  665.                            
  666.                             render.setColor( ( color[i].color[1] ):setA(255))
  667.                             render.drawRoundedBox(120, -1400+sizeX, 680 + i*180, 150, 150)
  668.  
  669.                             render.setMaterial(nil)
  670.                             render.drawPoly( {{ x = sizeX/2-150, y = 680 + i*180  }, { x = sizeX/2-200, y = 680 + i*180 + 150 }, { x = sizeX/2-450, y = 680 + i*180+150 }, { x = sizeX/2-400, y = 680 + i*180 }} )
  671.                            
  672.                             if inrange(8, 54 + i*14.5, 40, 12) then
  673.                                 click_possible = true
  674.                                 information(cx+4,cy+23, "" .. color[i].name .. " palettes" ,6400,font3)
  675.                             end
  676.                         end
  677.  
  678.                         if snd:isOnline() then else
  679.                             render.setMaterial(nil)
  680.                             if looping == true then render.setColor(Color(100,130,255):setA(255)) else render.setColor(Color(255,255,255):setA(75)) end
  681.                             render.drawPoly( {{ x = sizeX/2-150, y = 1200 + #color*180  }, { x = sizeX/2-200, y =  1200 + #color*180 + 200 }, { x = sizeX/2-650, y = 1200 + #color*180 + 200 }, { x = sizeX/2-600, y = 1200 + #color*180 }} )
  682.                         end
  683.                        
  684.                         render.setMaterial(nil)
  685.                         if show_visualizer == true then render.setColor(Color(100,130,255):setA(255)) else render.setColor(Color(255,255,255):setA(75)) end
  686.                         render.drawPoly( {{ x = sizeX/2-150, y = 1500 + #color*180  }, { x = sizeX/2-200, y =  1500 + #color*180 + 200 }, { x = sizeX/2-650, y = 1500 + #color*180 + 200 }, { x = sizeX/2-600, y = 1500 + #color*180 }} )
  687.                        
  688.                         render.setColor(Color(255,255,255))
  689.                         render.setFont(font2)
  690.                         render.drawSimpleText(sizeX/2-600, 1800 + #color*180, "ver. 2.18 (dev ver.)",0,1)
  691.                     else
  692.                         sizeToX, sizeToY = 0, 0
  693.  
  694.                         render.setColor(Color(255, 255, 255))
  695.                         render.setMaterial(mat[7])
  696.                         render.drawTexturedRectRotated(sizeX/2+110, 500+150, 300, 300,135)
  697.                     end
  698.  
  699.                     render.popMatrix()
  700.                    
  701.                     -------------------------------------------------------
  702.  
  703.                     -- Click logic
  704.                     --Pressed
  705.                     if changed(player():keyDown(IN_KEY.USE)) and player():keyDown(IN_KEY.USE) then
  706.                         markElement(true)
  707.                        
  708.                         if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
  709.                             color_menu = !color_menu
  710.                         end
  711.  
  712.                         for i=1, #color do
  713.                             if inrange(8, 54 + i*14.5, 40, 12) and color_menu == true then
  714.                                 use_color = i
  715.                             end
  716.                         end
  717.  
  718.                         if not snd:isOnline() and inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) or not snd:isOnline() and inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
  719.                             looping = !looping
  720.                         end
  721.                        
  722.                         if inrange(((sizeX/2-650)/6400)*512, ((1500 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
  723.                             show_visualizer = !show_visualizer
  724.                         end
  725.                     end
  726.                    
  727.                     --Released
  728.                     if player():keyDown(IN_KEY.USE) == false then
  729.                         markElement(false)
  730.                     end
  731.                    
  732.                     -------------------------------------------------------
  733.                    
  734.                     if inrange(((sizeX/2)/6400)*512, (500/6400)*512, (300/6400)*512, (300/6400)*512) then
  735.                         click_possible = true
  736.                     end
  737.                    
  738.                     if not snd:isOnline() and inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) or not snd:isOnline() and inrange(((sizeX/2-650)/6400)*512, ((1200 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
  739.                         click_possible = true
  740.                     end
  741.                        
  742.                     if inrange(((sizeX/2-650)/6400)*512, ((1500 + #color*180)/6400)*512, ( (sizeX/2-250) /6400)*512, (200/6400)*512) then
  743.                         click_possible = true
  744.                     end
  745.                    
  746.                     -- Draw slider
  747.                     for k, v in pairs(objects) do
  748.                         v:paint()
  749.  
  750.                         if v.can_change then
  751.                             if v.active then
  752.                                 v:think()
  753.                             else
  754.                                 if k == 2 then
  755.                                     v.val = time
  756.                                 end
  757.                             end
  758.                         else
  759.                             v:think()
  760.                         end
  761.                        
  762.                         if inrange(v.x,v.y,v.w,v.h) then
  763.                             click_possible = true
  764.                         end
  765.                     end
  766.                     -------------------------------------------------------
  767.                    
  768.                     if cx and cy then
  769.                         if click_possible then
  770.                             render.setColor(principal_color)
  771.                         else
  772.                             render.setColor(Color(255,255,255))
  773.                         end
  774.                        
  775.                         drawMouse(cx, cy)
  776.                     end
  777.                 end
  778.                
  779.             end)
  780.         end)
  781.     end
  782.    
  783.     -- Load video informations
  784.     function load_youtube(url)
  785.         local request_url = "https://michaelbelgium.me/ytconverter/convert.php?youtubelink=" .. url
  786.        
  787.         if http.canRequest() then
  788.             loading = string.replace(url, "https://www.youtube.com/watch?v=", "") .. ".mp3"
  789.            
  790.             http.get(request_url, function(data)
  791.                 URL = json.decode(data).file
  792.                 Name = json.decode(data).title
  793.                
  794.                 loading = "thumbnails.jpg"
  795.                
  796.                 timer.create("search background",2,1,function()
  797.                     http.get("https://www.googleapis.com/youtube/v3/videos?part=snippet%2Cstatistics&id="..string.replace(url, "https://www.youtube.com/watch?v=", "").."&key=AIzaSyD4Qt13HPWHwRBc_FBR6ITyBGILiFYM1uk", function(data)
  798.                         for v, item in pairs(json.decode(data).items) do
  799.                             if item.snippet.thumbnails.default then
  800.                                 background = item.snippet.thumbnails.default.url
  801.                                 b_size = Vector(120,90)*0.1
  802.                             end
  803.                            
  804.                             if item.snippet.thumbnails.medium then
  805.                                 background = item.snippet.thumbnails.medium.url
  806.                                 b_size = Vector(320,180)*0.2
  807.                             end
  808.                            
  809.                             if item.snippet.thumbnails.high then
  810.                                 background = item.snippet.thumbnails.high.url
  811.                                 b_size = Vector(480,360)*0.3
  812.                             end
  813.                            
  814.                             if item.snippet.thumbnails.standard then
  815.                                 background = item.snippet.thumbnails.standard.url
  816.                                 b_size = Vector(640,480)*0.6
  817.                             end
  818.                            
  819.                             if item.snippet.thumbnails.maxres then
  820.                                 background = item.snippet.thumbnails.maxres.url
  821.                                 b_size = Vector(1280,720)
  822.                             end
  823.                         end
  824.  
  825.                         hook.remove("render", "loading")
  826.                         load_texture()
  827.                     end)
  828.                 end)
  829.             end)
  830.         end    
  831.        
  832.         hook.add("render","loading",function()
  833.             local m = Matrix()
  834.             m:setScale(Vector(0.08))
  835.             render.pushMatrix(m)
  836.                    
  837.             render.setColor(Color(255))
  838.             render.setFont(font)
  839.             render.setFilterMag(1)
  840.  
  841.             if loading == "" then
  842.                 render.drawSimpleText(3200, 3200, lang.load_error.."",1,1)
  843.                 load_youtube(URL)
  844.             else
  845.                 render.drawSimpleText(3200, 3200, lang.load.." " .. loading .. "...",1,1)
  846.             end
  847.            
  848.             render.popMatrix()
  849.         end)
  850.     end
  851.     -------------------------------------------------------
  852.    
  853.     -- Load texture
  854.     function load_texture()
  855.         mat[1]:setTextureURL("$basetexture", background)
  856.         mat[2]:setTextureURL("$basetexture", "https://i.imgur.com/EkNra7d.png?2") // Use 512x512 resolution
  857.         //mat[2]:setTextureURL("$basetexture", "https://i.imgur.com/tXeR0gy.png") // Discord logo lol
  858.         mat[3]:setTexture("$basetexture", "particle/particle_glow_04")
  859.         mat[4]:setTexture("$basetexture", "vgui/gradient-u")
  860.         mat[5]:setTexture("$basetexture", "vgui/gradient-d")
  861.         mat[6]:setTexture("$basetexture", "vgui/gradient-l")
  862.         mat[7]:setTexture("$basetexture", "vgui/cursors/arrow")
  863.        
  864.         hook.add("render","loading",function()
  865.             local m = Matrix()
  866.             m:setScale(Vector(0.08))
  867.             render.pushMatrix(m)
  868.                    
  869.             render.setColor(Color(255))
  870.             render.setFont(font)
  871.             render.setFilterMag(1)
  872.  
  873.             render.drawSimpleText(3200, 3200, lang.load.." mat...",1,1)
  874.            
  875.             render.popMatrix()
  876.         end)
  877.        
  878.         hook.remove("render", "loading")
  879.         load()
  880.     end
  881.     -------------------------------------------------------
  882.    
  883.     -- Find update
  884.    
  885.     function findUpdate()
  886.         loading = "Checking update.."
  887.         if http.canRequest() then
  888.             http.get("https://pastebin.com/raw/sEvNPKaZ",function(data)
  889.                 version = string.split(data:sub(string.find(data:sub(1,150),"//version"),150)," ")[2]
  890.                
  891.                 if version != "2.18" then
  892.                     print(Color(70,255,70),lang.new_update .. "" .. version)
  893.                 else
  894.                     print(Color(70,255,70),lang.no_update .. "")
  895.                 end
  896.                
  897.                 loading = ""
  898.             end)
  899.         end
  900.     end
  901.     -------------------------------------------------------
  902.    
  903.     -- Permission setup
  904.     local perms = {
  905.         "render.screen",
  906.         "bass.loadURL",
  907.         "bass.play2D",
  908.         "material.create",
  909.         "material.urlcreate",
  910.         "light.create",
  911.         "http.get"
  912.     }
  913.    
  914.     if owner() == player() then
  915.         findUpdate()
  916.        
  917.         if list == "youtube" then
  918.             load_youtube(URL)
  919.         else
  920.             load_texture()
  921.         end
  922.     else
  923.         setupPermissionRequest(perms, lang.perm_description.."", true)
  924.  
  925.         if hasPermission("render.screen") then
  926.             hook.add("render", "perms", function()
  927.                 render.drawSimpleText(256, 256, lang.accept_perm.."", 1, 1)
  928.             end)
  929.         end
  930.  
  931.         hook.add("permissionrequest", "perms", function()
  932.             if permissionRequestSatisfied() then
  933.                 hook.remove("permissionrequest", "perms")
  934.                 hook.remove("render", "perms")
  935.                
  936.                 if list == "youtube" then
  937.                     load_youtube(URL)
  938.                 else
  939.                     load_texture()
  940.                 end
  941.             end
  942.         end)
  943.     end
  944.     -------------------------------------------------------
  945. end
RAW Paste Data