• Useful Code Snippets
    232 replies, posted
[QUOTE=Author.;46654790]Wan't to have some glowing text here and there, but don't know the maths? [lua] function Glow(speed,r,g,b,a) if speed then color = {} color.r = math.sin(RealTime()*(speed or 1))*r color.b = math.sin(RealTime()*(speed or 1))*g color.g = math.sin(RealTime()*(speed or 1))*b color.a = a or 255 return color.r, color.b, color.g, color.a end end [/lua] Example; [lua]surface.SetTextColor( Glow(5, 255, 0, 0) )[/lua] This will glow from red to black at a speed of five. Higher speeds will make it glow/blink faster. [vid]http://i.gyazo.com/18a920de483363e96468422cbfbe34c3.mp4[/vid][/QUOTE] How would I make this switch from one colour of my choice to another colour of my choice instead of black to a colour of my choice? For example, switch from grey to blue, instead of black to blue. This probably looks confusing at first glance :P
We should bring this thread back! So heres a little code that will have rotating text above a NPC not to complex but hey its pretty cool (you will need to make your own font) [code] surface.CreateFont( "LMMCTNPCBounceFont", { font = "Lato Light", size = 80, weight = 250, antialias = true, strikeout = false, additive = true, } ) local function LMMCTNPCBounceFunction() for k, v in pairs( ents.FindByClass( "lmm_ctnpc" ) ) do local p p = v:GetPos() + Vector(0,0,95 + math.sin(CurTime()*3)*5) for _,yaw in pairs({0, 180}) do local a = Angle(0, 0, 0) a:RotateAroundAxis(a:Forward(), 90) a:RotateAroundAxis(a:Right(), yaw) a:RotateAroundAxis(a:Right(), CurTime() * 15) render.PushFilterMag(TEXFILTER.ANISOTROPIC) render.PushFilterMin(TEXFILTER.ANISOTROPIC) cam.Start3D2D(p, a, 0.1) draw.DrawText("Chat tags NPC", "LMMCTNPCBounceFont", 0, 0, Color(0, 70, 128, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) cam.End3D2D() render.PopFilterMag() render.PopFilterMin() end end end hook.Add( "PostDrawOpaqueRenderables", "LMMCTNPCBounceFunction", LMMCTNPCBounceFunction) [/code] You will need to change the entity and change the text/functions! [video=youtube;-t6wiSGG6u4]https://www.youtube.com/watch?v=-t6wiSGG6u4&feature=youtu.be[/video]
Snippet to get info on player in a HUDDrawTargetID() hook. [CODE]function GM:HUDDrawTargetID() local ply = LocalPlayer() local trace = ply:GetEyeTrace() local ent = trace.Entity if (playermanager.GetClass(ent) == "player_default") then return true else return false end end[/CODE]
table.Select makes your life 10 times easier by only selecting values that conform to the given conditional function [B]Source:[/B] [code]function table.Select (tblMaster, bfuncCheck) local tblLocal = {} for k, v in pairs (tblMaster) do if bfuncCheck (v) then if type (k) != "number" then tblLocal[k] = v else tblLocal[#tblLocal + 1] = v end end end return tblLocal end[/code] [B]Example:[/B] [code]table.Select (player.GetAll (), function (ply) return ply:IsAdmin () end)[/code] [t]http://i.imgur.com/ibQEGdM.png[/t]
[QUOTE=Potatofactory;51223719]table.Select makes your life 10 times easier by only selecting values that conform to the given conditional function [B]Source:[/B] [code]function table.Select (tblMaster, bfuncCheck) local tblLocal = {} for k, v in pairs (tblMaster) do if bfuncCheck (v) then if type (k) != "number" then tblLocal[k] = v else tblLocal[#tblLocal + 1] = v end end end return tblLocal end[/code] [B]Example:[/B] [code]table.Select (player.GetAll (), function (ply) return ply:IsAdmin () end)[/code] [t]http://i.imgur.com/ibQEGdM.png[/t][/QUOTE] plz don't be like garry with your slow table utils. My implementation only supports numeric tables but it's substantially faster: [URL]https://github.com/SuperiorServers/dash/blob/master/lua/dash/extensions/table.lua#L1[/URL]
How is inpairs slower than incrementation?
[QUOTE=Potatofactory;51223992]How is inpairs slower than incrementation?[/QUOTE] It is quite noticeably slower if you call it a lot, that's because it does actual iteration instead of sequential indexed lookup. EDIT: It shouldn't be a problem if you use it only once/a few times though.
[QUOTE=StonedPenguin;51223901]plz don't be like garry with your slow table utils. My implementation only supports numeric tables but it's substantially faster: [URL]https://github.com/SuperiorServers/dash/blob/master/lua/dash/extensions/table.lua#L1[/URL][/QUOTE] Although his doesn't act directly on the table, instead creates a new tables and copies over the relevant entries. I would argue his is better, just for this fact.
[QUOTE=Potatofactory;51223719]table.Select makes your life 10 times easier by only selecting values that conform to the given conditional function[/QUOTE] why wouldn't you call this filter like everyone else in the world [url]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter[/url] [url]https://docs.python.org/2/library/functions.html#filter[/url] [url]http://php.net/manual/en/function.array-filter.php[/url] [url]https://developer.apple.com/reference/swift/array/1688383-filter[/url] [url]https://doc.rust-lang.org/std/iter/struct.Filter.html[/url] ... except for ruby [url]http://ruby-doc.org/core-2.2.0/Array.html#class-Array-label-Selecting+Items+from+an+Array[/url]
Since I can't remember if I posted this here before or not, [URL="https://github.com/MysteryPancake/GMod-Rainbows"]I made a bunch of rainbow functions[/URL] to help people draw rainbow stuff
Not sure if this is useful since most gamemodes are gun-based, but for those working on a melee-based gamemode, this code gives the player a shield. (Only worldmodel) [lua] local className = "whatever_entity_class" function giveShield( ply, mdl ) for _, v in ipairs( ply:GetChildren() ) do if v:GetClass() == className then v:Remove() end end local shield = ents.Create( className ) shield:SetMoveType( MOVETYPE_NONE ) shield:SetParent( ply ) shield:Fire( "SetParentAttachmentMaintainOffset", "anim_attachment_LH" ) shield:SetModel( mdl ) shield:SetLocalAngles( Angle( 180, 270, 260 ) ) shield:SetLocalPos( Vector( 16, 10, 30 ) ) shield:Spawn() end [/lua] Recommended to use with a custom entity so you have more control [lua] AddCSLuaFile() ENT.Base = "base_anim" if SERVER then function ENT:Initialize() -- Maybe some extra player stats here? end else function ENT:Draw() self:DrawModel() end -- Some client-side effects? end [/lua] Preview in shitty quality [media]https://www.youtube.com/watch?v=h1lAYwsCsWg[/media]
[QUOTE=dingusnin;51224373]Although his doesn't act directly on the table, instead creates a new tables and copies over the relevant entries. I would argue his is better, just for this fact.[/QUOTE] It's actually fairly slow to create a new table compared to recycling the old one. Using [URL="https://gist.github.com/aStonedPenguin/fcaec4e1619292d4e4b9281a068905e1"]this benchmark[/URL] I got these results: [t]https://fi1.es/hpOxA[/t] So it's roughly 31x faster in that test case...
[QUOTE=StonedPenguin;51227537]It's actually fairly slow to create a new table compared to recycling the old one. Using [URL="https://gist.github.com/aStonedPenguin/fcaec4e1619292d4e4b9281a068905e1"]this benchmark[/URL] I got these results: [t]https://fi1.es/hpOxA[/t] So it's roughly 31x faster in that test case...[/QUOTE] You can only really compare his Select and your FilterCopy, since these are the two functions which have similar functionality. in which case yours is only ~18% faster. And since the only major difference between Filter and FilterCopy is that the latter creates a new table, instead of modifying a pre-existing one. Also your benchmark tool isn't completely correct. Although in this case it should be fine, other cases might create create dependant states based on the previous execution. In other words, not all tests will be independent, and therefor won't yield an accurate benchmark for comparison against another test. You must recreate the same test conditions for each execution. In this particular, you've shown that t1 in Filter call-1 will not be the same as in call-2. Essentially all you've shown is creating a table is slow (which we already knew about for ages, and which is why trace callbacks have the option of supplying an argument for a table to dump the data in), and the ipairs/pairs is slower than index-looping (which... we already knew). For the ability to use it on all tables (as opposed to yours which will work unpredictably with non-sequential and not at all with non-numeric indexes) I'll take the extra 18% any day. I guess I'll stop derailing the thread further if I'm not supplying any content of my own.
IMO the best solution would be to just make both functions available (or use a bool to specify whether to reuse old table) so that you can use optimal one depending on the situation. Sometimes modifying original table might be preferred to creating a new one.
[QUOTE=dingusnin;51227627]Essentially all you've shown is creating a table is slow[/QUOTE] That's all he was trying to show. And I'd think you'd always know whether a table is sequential. To make up for this further derailing of the thread, I will share the following super-useful code snippet: [lua]do return end[/lua] It's beautiful, right? To give it some much-needed context, I made the file lua/autorun/client/luasandbox.lua which I use to test and fuck around in. Once I'm done testing something but I'm not quite sure if I'll need it again later, I put it below the "do return end" line. That way it never runs, but I don't have to go looking for it anywhere later, it's always going to be right there in that same file. Yes, it does become a big mess, but if I ever do need to pull up a piece of code it's certainly going to be near the top of the pile and not the bottom, so it's not a big problem. All code does needs to have correct syntax, but since it's a recycle bin for old code, that's never a problem.
Just making simple functions like the following will save you time with debugging and testing. [lua]function Me() return player.GetBySteamID("mysteamid") end concommand.Add("rmap", function() RunConsoleCommand("changelevel", game.GetMap()) end function EyeEntity() return Me():GetEyeTrace().Entity end[/lua]
[QUOTE=YourStalker;51227864]Just making simple functions like the following will save you time with debugging and testing. [lua]function Me() return player.GetBySteamID("mysteamid") end concommand.Add("rmap", function() RunConsoleCommand("changelevel", game.GetMap()) end function EyeEntity() return Me():GetEyeTrace().Entity or false end[/lua][/QUOTE] Not sure what you meant by "or false" in EyeEntity, but the "Entity" trace key will never be nil.
Some stuff I mostly stole from Falco's functional programming library: [code] --Stores variables "in" a function, so it can be called with fewer variables, or just some variables at the beginning next time function curry(f,...) local nargs = {...} return function(...) for k,v in pairs({...}) do nargs[1 + #nargs] = v end return f(unpack(nargs)) end end [/code] Usage: [code] dbprint = curry(print,"[DEBUG]") dbprint("Hello, world!") --Prints "[DEBUG] Hello world" [/code] [code] --Returns a function that calls each function passed, starting from the last going to the first, and passing the previous function's output as the next's input. function compose(...) local tfuncs = {...} return function(...) local results = {...} for i = #tfuncs,1,-1 do results = {tfuncs[i](unpack(results))} end return unpack(results) end end [/code] Usage: [code] printf = compose(print,string.format) printf("Thanks, I love %d!",5) --Prints "Thanks, I love 5!" query_s = compose(sql.Query,sql.SQLStr) query_s("Don't worry about ' OR 1=1-- sqli!") [/code] [code] --Takes a table, and returns some indexes function index(tbl,...) local results = {} for k,v in pairs({...}) do results[k] = tbl[v] end return unpack(results) end [/code] Usage: [code] words = { "Hello", "What", "A", "Beautiful", "World!", } print(index(words,1,5)) --Prints "Hello World!" [/code] [code] --Returns a function that calls each function passed, and appends each one's output to the last, and returns them all function amalgamate(...) local tfuncs = {...} return function(...) local results = {} for i = #tfuncs,1,-1 do results[#results + 1] = tfuncs[i](unpack({...})) end return unpack(results) end end [/code] Usage: [code] --chat.AddText is client side only notify = amalgamate( print, chat.AddText ) notify("Hello, world!") --Prints "Hello, world!" to chat and console [/code] I saw a code snippit somewhere with a print statement that told you where the print was and did some neat color things, here's a poor man's version of that. [code] --Bit of a hack, eh. function pass(...) return ... end traceprint = compose( print, curry(string.format,"%s:%s"), index, amalgamate( curry(pass,"currentline"), curry(pass,"short_src"), curry(debug.getinfo,3) ), print ) traceprint("Woah, how cool!") --Outputs "Woah, how cool!", a newline, then "<file location>.lua:<line number>" [/code]
[QUOTE=Apickx;51230357] [code] --Stores variables "in" a function, so it can be called with fewer variables, or just some variables at the beginning next time function curry(f,...) local nargs = {...} return function(...) return f(unpack(nargs),...) end end [/code][/QUOTE] unpack is going to be cut to one argument because of the varargs
[QUOTE=bigdogmat;51230792]unpack is going to be cut to one argument because of the varargs[/QUOTE] oshit, I could have sworn I fixed that :S thanks.
[QUOTE=zerf;51224457]why wouldn't you call this filter like everyone else in the world [url]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter[/url] [url]https://docs.python.org/2/library/functions.html#filter[/url] [url]http://php.net/manual/en/function.array-filter.php[/url] [url]https://developer.apple.com/reference/swift/array/1688383-filter[/url] [url]https://doc.rust-lang.org/std/iter/struct.Filter.html[/url] ... except for ruby [url]http://ruby-doc.org/core-2.2.0/Array.html#class-Array-label-Selecting+Items+from+an+Array[/url][/QUOTE] He was probably thinking of SQL "SELECT" statements.
I approve of the amount of functional programming happening in this thread.
[lua]local maps = { gm_construct = { 2415, 2416, 2417, 2426 } } hook.Add("InitPostEntity", "RemoveMapEntities", function() local moveents = maps[game.GetMap()] if not moveents then return end for _, MapCreationID in ipairs(moveents) do local ent = ents.GetMapCreatedEntity(MapCreationID) if IsValid(ent) then ent:Remove() end end end)[/lua] Put this in a server autorun file to remove the selected map-created entities from the map. Can easily add entities from different maps and they don't interfere with each other. To find the MapCreationID of the entity, open the map in singleplayer, look directly at the entity and run this command in the console: [code]lua_run print(Entity(1):GetEyeTrace().Entity:MapCreationID())[/code]
How can a map created entity not be valid, although if entities doesn't exists, it won't be created
[QUOTE=gonzalolog;51254042]How can a map created entity not be valid, although if entities doesn't exists, it won't be created[/QUOTE] * It costs nothing to make that check. Performance is meaningless in places like that (code that only runs once), as long as it doesn't take more than a few seconds to run (which it doesn't come close to). * Another function hooked to InitPostEntity could have deleted it before this, depending on the order of execution which we have no control over. * It's a good practice even if it never could have happened.
little snippet to stop guessing label width every time :3 might be shitcoded so take care~ [code] local PANEL = {} function PANEL:Init() self.text = "Dummy" self.font = "Default" end function PANEL:Font(name) self.font = name end function PANEL:SetText(t) self.text = t surface.SetFont( self.font ) if w != select( 1, surface.GetTextSize( self.text )) and h != select( 2, surface.GetTextSize( self.text )) then self:Size(select( 1, surface.GetTextSize( self.text )), select( 2, surface.GetTextSize( self.text ))) end end function PANEL:Size(w, h) self:SetSize(w, h) end function PANEL:Paint(self, w, h) draw.SimpleText( self.text, self.font, 0, 0, Color(255,255,255) ) end vgui.Register("iLabel", PANEL, "DLabel") [/code]
[QUOTE=igodsewer;51254325]little snippet to stop guessing label width every time :3 might be shitcoded so take care~ [code] local PANEL = {} function PANEL:Init() self.text = "Dummy" self.font = "Default" end function PANEL:Font(name) self.font = name end function PANEL:SetText(t) self.text = t surface.SetFont( self.font ) if w != select( 1, surface.GetTextSize( self.text )) and h != select( 2, surface.GetTextSize( self.text )) then self:Size(select( 1, surface.GetTextSize( self.text )), select( 2, surface.GetTextSize( self.text ))) end end function PANEL:Size(w, h) self:SetSize(w, h) end function PANEL:Paint(self, w, h) draw.SimpleText( self.text, self.font, 0, 0, Color(255,255,255) ) end vgui.Register("iLabel", PANEL, "DLabel") [/code][/QUOTE] Ehm, [I]myShittyLabel:SizeToContents()[/I], no?
[QUOTE=mijyuoon;51254861]Ehm, [I]myShittyLabel:SizeToContents()[/I], no?[/QUOTE] SizeToContents() is gud but sometimes i use this one instead of sizetocontents because sometimes i need to set background with extra paddings (yk buttons, bootstrap-like labels and so on) or set icon in front of label and so on afaik SizeToContents() only sizes to text, but not to other stuff drawn by surface. or draw. stuff but here i can set margins with w+N or h+N might be wrong at some point
Single-argument Color function that influences grayscale (should be default for gmod imo). Pretty useful for those who got used to other programming languages, or are just lazy. [lua] local oldClr = oldClr or Color function Color( r, g, b, a ) if ( ( r ~= nil ) and ( g == nil ) ) then return oldClr( r, r, r ) else return oldClr( r, g, b, a ) end end [/lua] Makes it easier to use the common white & black colors, for example [lua] Color( 255 ) -- White Color( 0 ) -- Black Color( 255, 0, 0 ) -- Red, like normally [/lua]
[QUOTE=Skere_;51291625]Single-argument Color function that influences gray-scale (should be default for gmod imo). Pretty useful for those who got used to other programming languages, or are just lazy. [lua] local oldClr = oldClr or Color function Color( r, g, b, a ) if ( ( r ~= nil ) and ( g == nil ) ) then return oldClr( r, r, r ) else return oldClr( r, g, b, a ) end end [/lua] Makes it easier to use the common white & black colors, for example [lua] Color( 255 ) -- White Color( 0 ) -- Black Color( 255, 0, 0 ) -- Red, like normally [/lua][/QUOTE] Or just use color_white and color_black.
Sorry, you need to Log In to post a reply to this thread.