• Useful Code Snippets
    232 replies, posted
This is a bit more of a snippet, but some guy messaged me about a slot machine, and how you could make one. I had no idea, so I tried to make one myself. It should be quite fast thanks to NetworkVar not working as I thought it would, making me rewrite it to be almost entirely serverside based. It should be easy enough to change it to do what you want it to. :snip: It's on GitHub now since I keep changing it every 5 seconds [url]https://github.com/MysteryPancake/Fun/blob/master/gmod/slotmachine.lua[/url] [video=youtube;2SM211R0aNE]https://www.youtube.com/watch?v=2SM211R0aNE[/video] [editline]20th July 2017[/editline] [URL="https://github.com/MysteryPancake/Fun"]Also, this repo is full of stuff you might want to play with some day[/URL]
Made a tool that compares two savetables and prints difference. Useful for debugging. [lua] TOOL.Name = "Savetable test" TOOL.Category = "Debug" TOOL.Information = { {name = "left"}, {name = "right"}, {name = "reload"} } if ( CLIENT ) then language.Add( "Tool.savetabletest.name", "Savetable test" ) language.Add( "Tool.savetabletest.desc", "" ) language.Add( "Tool.savetabletest.left", "Select first savetable." ) language.Add( "Tool.savetabletest.right", "Select second savetable." ) language.Add( "Tool.savetabletest.reload", "Print savetable difference." ) end local hasfirsttable = false local hassecondtable = false local firstsavetable = {} local secondsavetable = {} function TOOL:LeftClick(tr) if(tr.Hit and tr.Entity and tr.Entity:IsValid()) then local firsttable = tr.Entity:GetSaveTable() local firstkeytable = table.GetKeys(firsttable) local i = 1 firstsavetable = {} for _, f in pairs(firsttable) do table.insert(firstsavetable, tostring(firstkeytable[i]) .. " " .. tostring(f)) i = i + 1 end print("First table " .. tostring(tr.Entity) .. " count=" .. tostring(table.Count(firstsavetable))) hasfirsttable = true return true end end function TOOL:RightClick(tr) if(tr.Hit and tr.Entity and tr.Entity:IsValid()) then local secondtable = tr.Entity:GetSaveTable() local secondkeytable = table.GetKeys(secondtable) local i = 1 secondsavetable = {} for _, s in pairs(secondtable) do table.insert(secondsavetable, tostring(secondkeytable[i]) .. " " .. tostring(s)) i = i + 1 end print("Second table " .. tostring(tr.Entity) .. " count=" .. tostring(table.Count(secondsavetable))) hassecondtable = true return true end end function TOOL:Reload(tr) if(hasfirsttable==true && hassecondtable==true) then local diftable = secondsavetable local fi = 1 for fi=1, table.Count(firstsavetable) do local fst = tostring(firstsavetable[fi]) local si = 1 for si=1, table.Count(secondsavetable) do local sst = tostring(secondsavetable[si]) if(fst==sst) then table.remove(diftable, si) end end end PrintTable(diftable) end end [/lua]
I know people were asking about this in a couple posts but I can't find them, here's a php function that will query a gmod server and return player amount and stuff like that. [I]It's not mine, I didn't make it[/I]. I found it on some old forum, can't remember where otherwise I would post the link. [LUA]function query_source($address) { $array = explode(":", $address); $server['status'] = 0; $server['ip'] = $array[0]; $server['port'] = $array[1]; if (!$server['ip'] || !$server['port']) { exit("EMPTY OR INVALID ADDRESS"); } $socket = @fsockopen("udp://{$server['ip']}", $server['port'], $errno, $errstr, 1); if (!$socket) { return $server; } stream_set_timeout($socket, 1); stream_set_blocking($socket, TRUE); fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00"); $packet = fread($socket, 4096); @fclose($socket); if (!$packet) { return $server; } $header = substr($packet, 0, 4); $response_type = substr($packet, 4, 1); $network_version = ord(substr($packet, 5, 1)); if ($response_type != "I") { exit("NOT A SOURCE SERVER"); } $packet_array = explode("\x00", substr($packet, 6), 5); $server['name'] = $packet_array[0]; $server['map'] = $packet_array[1]; $server['game'] = $packet_array[2]; $server['description'] = $packet_array[3]; $packet = $packet_array[4]; $server['players'] = ord(substr($packet, 2, 1)); $server['playersmax'] = ord(substr($packet, 3, 1)); $server['vac'] = ord(substr($packet, 8, 1)); return $server; } [/LUA]
Something I'm going to be using in every single entity I make that is a pain in the ass to keep upright from now on. [CODE]local useCount = 0 function ENT:Use(activator, caller) -- double press :D useCount = useCount + 1 timer.Simple(0.2, function() useCount = 0 end) if (useCount == 2) then local ang = self:GetAngles() local pos = self:GetPos() + Vector(0, 0, 5) self:SetAngles(Angle(0, 180 + caller:GetAngles().yaw, 0)) self:SetPos(pos) -- there was a bug where the ent would stay frozen in the air, rewaking the physics seems to fix the issue. local phys = self:GetPhysicsObject() if (phys:IsValid()) then phys:Wake() end end end[/CODE]
Function to replace a panels MoveTo function with the type of Easing you wish: [CODE] local function inQuad(t, b, c, d) t = t / d return c * math.pow(t, 2) + b end local function outQuad(t, b, c, d) t = t / d return -c * t * (t - 2) + b end local function inOutQuad(t, b, c, d) t = t / d * 2 if t < 1 then return c / 2 * math.pow(t, 2) + b else return -c / 2 * ((t - 1) * (t - 3) - 1) + b end end local moveType = { ["in"] = inQuad, ["out"] = outQuad, ["inout"] = inOutQuad } local function MoveToCustomAnimSetup(pnl, type) pnl.OldThink = pnl.Think local toFunc = moveType[type] pnl.CustomAnim = Derma_Anim("MoveTo", pnl, function(this, anim, delta, data) if anim.Started then data.startX = this.x data.startY = this.y data.endX = data.x data.endY = data.y end local endDelta = toFunc(delta, 0, 1, 1) local toX, toY = Lerp(endDelta, data.startX, data.endX), Lerp(endDelta, data.startY, data.endY) this:SetPos(toX, toY) if anim.Finished then this:SetPos(data.endX, data.endY) if this.CustomAnimCallback then this.CustomAnimCallback() end end end) pnl.Think = function(this) if this.OldThink then this:OldThink() end if this.CustomAnim:Active() then this.CustomAnim:Run() end if this.DelayedAnims and !this.CustomAnim:Active() then for k, v in pairs(this.DelayedAnims) do if v[3] <= RealTime() then this.CustomAnim:Start(v[1], v[2]) this.DelayedAnims[k] = nil end end end end pnl.MoveTo = function(this, x, y, time, delay, _, callback) this.CustomAnimCallback = callback local data = {x = x, y = y} if delay and delay > 0 then if !this.DelayedAnims then this.DelayedAnims = {} end table.insert(this.DelayedAnims, {time, data, RealTime() + delay}) else this.CustomAnim:Start(time, data) end end end [/CODE] Easing functions taken from: [url]https://github.com/EmmanuelOga/easing[/url] This function basically replaces the MoveTo function to use easing. Just call the function MoveToCustomAnimSetup with argument 1 being the panel and argument 2 being the type of easing you wish for the panel to use.
[QUOTE=MrRalgoman;52500679]I know people were asking about this in a couple posts but I can't find them, here's a php function that will query a gmod server and return player amount and stuff like that. [I]It's not mine, I didn't make it[/I]. I found it on some old forum, can't remember where otherwise I would post the link. [LUA]function query_source($address) { $array = explode(":", $address); $server['status'] = 0; $server['ip'] = $array[0]; $server['port'] = $array[1]; if (!$server['ip'] || !$server['port']) { exit("EMPTY OR INVALID ADDRESS"); } $socket = @fsockopen("udp://{$server['ip']}", $server['port'], $errno, $errstr, 1); if (!$socket) { return $server; } stream_set_timeout($socket, 1); stream_set_blocking($socket, TRUE); fwrite($socket, "\xFF\xFF\xFF\xFF\x54Source Engine Query\x00"); $packet = fread($socket, 4096); @fclose($socket); if (!$packet) { return $server; } $header = substr($packet, 0, 4); $response_type = substr($packet, 4, 1); $network_version = ord(substr($packet, 5, 1)); if ($response_type != "I") { exit("NOT A SOURCE SERVER"); } $packet_array = explode("\x00", substr($packet, 6), 5); $server['name'] = $packet_array[0]; $server['map'] = $packet_array[1]; $server['game'] = $packet_array[2]; $server['description'] = $packet_array[3]; $packet = $packet_array[4]; $server['players'] = ord(substr($packet, 2, 1)); $server['playersmax'] = ord(substr($packet, 3, 1)); $server['vac'] = ord(substr($packet, 8, 1)); return $server; } [/LUA][/QUOTE] Remember that there are also [URL="https://github.com/koraktor/steam-condenser-php"]libraries[/URL] that can do this [URL="https://github.com/xPaw/PHP-Source-Query"]better[/URL] if you want to use this in production. :) I made a program in Java that uses this protocol along with redis to provide an [URL="https://github.com/Buttwaters/API"]HTTP API[/URL] for our servers.
This can be very useful if you are like garry and just hate everyone. [code] for k,v in pairs (player.GetAll()) do v:Kill() end [/code]
Here's a basic example of how to use render.RenderView in a 3D2D context. I thought it was cool since you can use it for portals and other stuff. [CODE] local rendering = false local rt = GetRenderTarget( "RenderView", ScrW(), ScrH(), true ) local mat = CreateMaterial( "UnlitGeneric", "GMODScreenspace", { [ "$basetexturetransform" ] = "center .5 .5 scale -1 -1 rotate 0 translate 0 0", [ "$texturealpha" ] = "0", [ "$vertexalpha" ] = "1" } ) hook.Add( "PostDrawOpaqueRenderables", "RenderView", function( depth, skybox ) if rendering or skybox then return end local tr = LocalPlayer():GetEyeTrace() local pos = tr.HitPos local ang = tr.HitNormal:Angle() ang:RotateAroundAxis( ang:Up(), -90 ) render.PushRenderTarget( rt ) render.Clear( 0, 0, 0, 255, true, true ) rendering = true render.RenderView( { x = 0, y = 0, w = ScrW(), h = ScrH(), origin = pos, angles = EyeAngles() } ) rendering = false render.PopRenderTarget() cam.Start3D2D( pos, ang, 1 ) mat:SetTexture( "$basetexture", rt ) surface.SetDrawColor( 255, 255, 255 ) surface.SetMaterial( mat ) surface.DrawTexturedRect( -ScrW() / 2, -ScrH() / 2, ScrW(), ScrH() ) cam.End3D2D() end ) [/CODE] Here's what it can look like: [t]https://steamuserimages-a.akamaihd.net/ugc/857229700345504362/1F64CE4727B48B075485CE498D564770E1BDF57B/[/t]
Easily create Color ConVars which store full colors. Then index any of them with convar:GetColor() to get the whole color. local tbl = {} -- our archive local convar = FindMetaTable("ConVar") function convar:GetColor() local name = self:GetName():sub(1,-3) --trim the _r local r = tbl[name.."_r"]:GetInt() local g = tbl[name.."_g"]:GetInt() local b = tbl[name.."_b"]:GetInt() local a = tbl[name.."_a"] if a then a = a:GetInt() end return Color(r,g,b,a or 255) end -- (Convar name, default value, whether to archive, [whether to use alpha]) function CreateColorConVar(name,def,save,alpha) local namer, nameg, nameb, namea = name.."_r", name.."_g", name.."_b", name.."_a" local r = CreateClientConVar(namer,def.r,save or false,false) local g = CreateClientConVar(nameg,def.g,save or false,false) local b = CreateClientConVar(nameb,def.b,save or false,false) local a if alpha then a = CreateClientConVar(namea,def.a,save or false,false) end tbl[namer] = r tbl[nameg] = g tbl[nameb] = b tbl[namea] = a return r end Dropbox Download
You should use CreateConVar; CreateClientConVar is just an alias now and should really be deprecated.
Nothing wrong with using a convenience function.
It doesn't really provide a convenience is problem, it just lacks more features.
Already stolen 'Tis the season to spice up your derma!
I recommend surface.DrawTexturedRectUV instead of surface.DrawPoly
@Bobblehead your Dropbox links don't work anymore.
Fixed.
I put this on another thread awhile ago, but this snippet I wrote allows you to draw gradients in realtime, and change the color per corner. Very handy if you don't want to pre-make your gradients using a texture.     local pars =     {         ["$ignorez"]=1,         ["$vertexcolor"]=1,         ["$vertexalpha"]=1     }     local gradmat = CreateMaterial("gradientMat2", "UnlitGeneric", pars);          //    util.DrawGradient     //    Arguments:     //    x, y = top left position     //    w, h =width and height     //     col1 = topleft color, col2 = topright color, col3 = bottom left color, col4 = bottom right color     //    Written by Brassx STEAM_0:1:40846692     function util.DrawGradient(x, y, w, h, col1, col2, col3, col4)                  render.SetMaterial(gradmat);           mesh.Begin( MATERIAL_QUADS, 1 );             mesh.Color(col1.r, col1.g, col1.b, col1.a);             mesh.TexCoord( 0,0,0 );             mesh.Position( Vector(x, y, 0) );             mesh.AdvanceVertex();                              mesh.Color(col2.r, col2.g, col2.b, col2.a);             mesh.TexCoord( 0,1,0 );             mesh.Position( Vector(x + w, y, 0) );             mesh.AdvanceVertex();                                      mesh.Color(col4.r, col4.g, col4.b, col4.a);             mesh.TexCoord( 0,1,1 );             mesh.Position( Vector(x + w, y + h, 0) );             mesh.AdvanceVertex();                          mesh.Color(col3.r, col3.g, col3.b, col3.a);             mesh.TexCoord( 0,0,1 );             mesh.Position( Vector(x, y + h, 0) );             mesh.AdvanceVertex();         mesh.End()     end Example: hook.Add("HUDPaint", "testGradients", function() util.DrawGradient(100, 100, 256, 256, Color(200, 0, 0, 255), Color(0, 200, 0, 255), Color(0, 0, 200, 255), Color(200, 200, 0, 255)); end) https://i.gyazo.com/2c3c533abbe2a50d1d33a989306a0c9a.png
And in case you don't want to break graphics if something goes wrong, here you go linear gradients using textures local color_from, color_to = color_white, color_black function surface.SetGradient(a,b) color_from = a color_to = b end local gradient = surface.GetTextureID("vgui/gradient-u") --Min arguments: x,y,w,h --angle: Gradient angle (default 0) --scale: how big the gradient is (default 1) --passes: how many passes do you want with it (below 3 shows some transparency in the middle) (default) function surface.DrawGradient(x, y, w, h, angle, scale, passes) --We get the max size by obtaining the hipotenuse from the width and height local max = math.sqrt(h^2+w^2) * (scale or 1) surface.SetTexture(gradient) --We cut anything we don't need render.SetScissorRect( x, y, x+w, y+h, true ) --We need to do multiple passes because there are some transparency for k=1,passes or 3 do surface.SetDrawColor(color_from) surface.DrawTexturedRectRotated(x+w/2, y+h/2, max, max, angle or 0) surface.SetDrawColor(color_to) surface.DrawTexturedRectRotated(x+w/2, y+h/2, max, max, (angle or 0) + 180) end render.SetScissorRect( 0, 0, 0, 0, false ) end hook.Add("HUDPaint","TestGradients", function() surface.SetGradient(Color(255,0,0), Color(0,255,0)) surface.DrawGradient(256,256,256,128,90, 1, 10) end)
Sorry, you need to Log In to post a reply to this thread.