• A function that works only after it has been removed
    1 replies, posted
Hi, I have a rather strange problem, I try to add the effect of falling snow to my scoreboard, but something strange happens. This is the script for snow animation (located in autorun / client): local NEGPI2 = math.pi * -2 local snowmaxstartheight = -1.5 local snowflakeminsize = 0.1 local segmentslowerbound,segmentsupperbound = 6,9 local radiuslowerbound,radiusupperbound = 2,5 local snowflakefallspeed = 80 local snowflakeshrinkspeed = 1 local Segments = {} local function GenerateSegments(seg) Segments[seg] = {} for i = 1, seg do local a = (i / seg) * NEGPI2 Segments[seg][i] = {math.sin( a ),math.cos( a )} end return Segments[seg] end function draw.Circle( x, y, radius, seg ) local cir = {} local segments = Segments[seg] or GenerateSegments(seg) for i = 1,seg do cir[i] = {x = x + segments[i][1] * radius, y = y + segments[i][2] * radius} end surface.DrawPoly( cir ) end function DrawSnow(pnl, amt) pnl.snowtbl = {} for i = 1,amt do pnl.snowtbl[i] = {math.random(pnl:GetTall() * snowmaxstartheight, 0),math.random(pnl:GetWide()),math.random(radiuslowerbound,radiusupperbound),math.random(segmentslowerbound,segmentsupperbound)} end     local snowtbl = pnl.snowtbl     surface.SetDrawColor(230, 230, 250, 200)     draw.NoTexture()     for i = 1, amt do         if (snowtbl[i][1] >= pnl:GetTall()) then             snowtbl[i][3] = Lerp(snowflakeshrinkspeed * FrameTime(), snowtbl[i][3], 0)             if (snowtbl[i][3] <= snowflakeminsize) then                 snowtbl[i][1] = math.random(pnl:GetTall() * snowmaxstartheight,0)                 snowtbl[i][2] = math.random(pnl:GetWide())                 snowtbl[i][3] = math.random(radiuslowerbound,radiusupperbound)                 snowtbl[i][4] = math.random(segmentslowerbound,segmentsupperbound)             end         else             snowtbl[i][1] = math.Approach(snowtbl[i][1], pnl:GetTall(), snowflakefallspeed * FrameTime())         end         draw.Circle( snowtbl[i][2], snowtbl[i][1], snowtbl[i][3], snowtbl[i][4] )     end end In sb_main, in "function PANEL:Paint()" I have this: DrawSnow(self, 50) And here the problem arises - when everything is done as I have presented, the snow blocks on the upper edge and does not fall down, only after removing this part everything works as it should: pnl.snowtbl = {} for i = 1,amt do pnl.snowtbl[i] = {math.random(pnl:GetTall() * snowmaxstartheight, 0),math.random(pnl:GetWide()),math.random(radiuslowerbound,radiusupperbound),math.random(segmentslowerbound,segmentsupperbound)} end However, after rebooting the server without providing some of the functions, the script does not work at all, so that it works, I have to do the following: - Use the entire script that I gave at the beginning, - delete the given part of the function when the server is on. However, just change the map, and again nothing works, someone knows what can be done with it?
Based on about 15 minutes of cocking around on my own, after years of getting out of this game. I think I know what's going on. As you're calling DrawSnow in the PANEL:Paint hook, every single frame your table of snowflakes is being recreated, meaning they never have a chance to travel, as a frame is just took damn fast. Instead what you should really be doing is creating that table of snowflakes within the PANEL:Init hook. This way the 50, 150, 5000+ snowflakes you want to make float down are created once, and their positions are persisted between frames correctly. I was only able to get it working myself after creating a new Panel type that derived DPanel, there's probably better ways of going about that, but like I said, I've been out of the game far too long. I ended up with some along the lines of this; function scoreboard:init(amt)     local SNOWPANEL = {}     function SNOWPANEL:Init()         self.snowtbl = {}              for i = 1,amt do             self.snowtbl[i] = {math.random(self:GetTall() * snowmaxstartheight, 0),math.random(self:GetWide()),math.random(radiuslowerbound,radiusupperbound),math.random(segmentslowerbound,segmentsupperbound)}         end     end     vgui.Register( "SnowPanel", SNOWPANEL, "DPanel" )          local panel = vgui.Create( "SnowPanel" ) -- Standard panel construction     function panel:Paint()         scoreboard:DrawSnow(self)     end     scoreboard.panel = panel end function scoreboard:show()     if (!scoreboard.panel) then         scoreboard:init(50)     end     scoreboard.panel:Show()     function scoreboard:hide()         scoreboard.panel:Hide()     end end The definition of DrawSnow no longer needs the "amt" parameter as you can just grab the length of the snowtbl easily enough; function scoreboard:DrawSnow(pnl)     local snowtbl = pnl.snowtbl or {} surface.SetDrawColor(230, 230, 250, 200) draw.NoTexture() for i = 1, #snowtbl do -- Everything else end After seeing the flakes buzzing around like madmen and you mentioning it goes away when you remove the creation loop, that was a big giveaway that it was just some kind of table data being replaced every frame. Be cautious about doing complex work or assignments within hooks such as Paint, they're called every single frame, and if you're not careful can annihilate performance.
Sorry, you need to Log In to post a reply to this thread.