Useful Code Snippets

I’ve got quite a few pieces of code which I’ve figured out and would’ve been very helpful to me like 2 months ago, so I made a place for people to post snippets of code for others to learn from. Whether it be like an undocumented or poorly documented wiki function, a cool thing you discovered, or just a basic snippet of code. It could be 5 lines of code or even 100 l ines of code, as long as you think its useful then feel free to post it.

Draw 3d2d text above a player’s head



local BoneIndx = ply:LookupBone("ValveBiped.Bip01_Head1")
local BonePos, BoneAng = ply:GetBonePosition( BoneIndx )
local pos = BonePos + Vector(0,0,80) -- Place above head bone
local eyeang = LocalPlayer():EyeAngles().y - 90 -- Face upwards
local ang = Angle( 0, eyeang, 90 )

-- Start drawing 
cam.Start3D2D(pos, ang, 0.1)
	draw.DrawText( ply:Nick(), "Trebuchet24", 0, 400, Color(0,0,0), TEXT_ALIGN_CENTER )
cam.End3D2D()


Having a shape decrease in height based on a timer (dont use this many variables lol)



local Height = 30 -- Shape's maximum height
local BaseTime = 30 -- How long the timer runs
timer.Create("TestTimer", BaseTime, 0, function() print("Done") end) -- Timer to reference

local Time = math.Round( timer.TimeLeft("TestTimer") or 0, 1) -- Round the time
local TimeLeft = math.Clamp( Time, 0, BaseTime ) -- Clamp the time
local Seg = Height / BaseTime -- Divide the shape into segments
local Bar = math.Clamp(TimeLeft * Seg, 0, Height) -- Multiply the time into the segments


Helper function for surface.GetTextSize



function GetTextSize(text, font)
	surface.SetFont(font)
	local w, h = surface.GetTextSize(text)
	return w, h
end

local width, height = GetTextSize("Hello", "Trebuchet24")


– Drawing a grid on your screen (from LuaBee’s poly editor)



local GridSize = 20
PANEL.Paint = function()
	for i=GridSize, ScrW(), GridSize do
		surface.DrawLine(i, 0, i, ScrH())
		surface.DrawLine(0, i, ScrW(), i)
	end
end


The text above players head helped. Thanks :slight_smile:

[lua]local myscrw, myscrh = 1280, 600

function SizeW(width)
local screenwidth = myscrw
return width*ScrW()/screenwidth
end

function SizeH(height)
local screenheight = myscrh
return height*ScrH()/screenheight
end

function SizeWH(width, height)
local screenwidth = myscrw
local screenheight = myscrh
return widthScrW()/screenwidth, heightScrH()/screenheight
end[/lua]
I always find it hard to use maths to make huds, so I just have this laying at the side. Basically it takes you’re screen width and height (modify at the top), then it does some maths and returns an amount of pixels depending on the screen size of all other players, and modifies the sizes to fit like it fit your screen size.

Example;
[lua]surface.DrawRect(SizeW(100), SizeH(100), SizeW(200), SizeH(300))[/lua]

[editline]n[/editline]

A simple function to draw rectangle materials…?

[lua]function DrawTexturedRect(x,y,w,h,mat)
local mat = Material(mat)
surface.SetMaterial(mat)
surface.SetDrawColor(255,255,255)
surface.DrawTexturedRect(x,y,w,h)
end[/lua]

Positioning of your object in the midlle of your SpawnIcon
[lua]local Ent = ModelPanel:GetEntity()
PrevMins, PrevMaxs = Ent:GetRenderBounds()
ModelPanel:SetCamPos((PrevMins:Distance(PrevMaxs))*Vector(1, 1, 0.5))
ModelPanel:SetLookAt((PrevMaxs + PrevMins)*Vector(0.5, 0.5, 0.5))[/lua]

I actually have plenty of these, but I’ll post the ones people can’t figure themself that easily.

Making DModelPanels camera point at the middle of model and set cameras position according to models scale to prevent it from going outside the panel since I had a problem like that.


local mn, mx = mdlpnl.Entity:GetRenderBounds()
local size = 0
size = math.max( size, math.abs(mn.x) + math.abs(mx.x) )
size = math.max( size, math.abs(mn.y) + math.abs(mx.y) )
size = math.max( size, math.abs(mn.z) + math.abs(mx.z) )

mdlpnl:SetFOV( 45 )
mdlpnl:SetCamPos( Vector( size, size, size ) )
mdlpnl:SetLookAt( (mn + mx) * 0.5 )

This also helped! thanks!



collectgarbage("stop");
for i = 1, 10000000
    string.rep(" ", i)
end


this code basically makes gmod super fast and definitely doesn’t break windows


(User was banned for this post ("Needs a time out; repeated shitposting" - NiandraLades))

github.com/zerfgog/GLua-Snippets

[editline]6th December 2014[/editline]

Muh links
github.com/zerfgog/GLua-Snippets

Any useful snippet for making custom sandbox scoreboard? I think that it is hard to find solution as i cant itself.

Derma with some docking = Scoreboard

Well, when i looked gmods messy scoreboard code, they used command and surface.draw but no derma?

[lua]
local temp
local extra = -math.pi / 2

local function DrawPartialSquare(x, y, size, percent, steps)
steps = steps or 10
size = size / 2
x = x + size
y = y + size
percent = math.Clamp(percent or 0.5, 0, 1) * 2 * math.pi

local radius = math.sqrt(2 * (size ^ 2))

if (percent == 0) then
	return
end

temp = {{x = x, y = y}}

local i

for k = 0, (percent * steps) do
	i = Lerp(k / steps, 0, percent)
	temp[#temp + 1] = {x = math.Clamp(x + math.cos(i + extra)*radius, x - size, x + size), y = math.Clamp(y + math.sin(i + extra)*radius, y - size, y + size)}
end

temp[#temp + 1] = temp[1]

surface.DrawPoly(temp)

end
[/lua]

Draws a slightly filled square starting at (x, y). The width and height of the square are defined by the third argument.

Looks like this:

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.

How could i use the text above a players head on my gamemode?

The TTT equipment item code (not by me) from this thread I posted



EQUIP_TESTITEM = 256 -- Power of 2 ID, it must not be used by any other items

hook.Add( "InitPostEntity", "LoadYourItemThing", function() 
       local TestPassive = {
              id = EQUIP_TESTITEM, 
              loadout = false, -- Whether or not the role has it by default 
              type = "item_passive", 
              material = "vgui/ttt/passive_item.png",
              name = "Passive Item",
              desc = "THIS DOES STUFF. BUY IT!"
      }
      table.insert( EquipmentItems[ROLE_TRAITOR], TestPassive ) -- Insert your item into the correct Role menu
end) 
-- Now add hooks and stuff to whatever you want down here


Online map image checking from Gametracker, I modified the one from Tomelyr’s Server Hopping Bunny (with his help) to use in my map vote.



local map = "ttt_67thway_v3"

local Url = "http://image.www.gametracker.com/images/maps/160x120/garrysmod/"..map..".jpg" 
local MapImgUrl = "https://raw.githubusercontent.com/Exho1/Images/master/materials/noicon_map.png"
local PHPUrl = ""

-- HTTP Checking of map images from Gametracker
http.Post( PHPUrl, {url = Url}, -- Send the map url to our PHP test
nil, -- Nil the callback, dont need it
function(error) -- Error message
	print("[Error] Unable to check map image of: "..map)
end) 
http.Fetch( PHPUrl.."?url="..Url, -- Grab the PHP data
function ( body, len, headers, code )
	if string.find( body, "true") then
		MapImgUrl = "http://image.www.gametracker.com/images/maps/160x120/garrysmod/"..map..".jpg" 
	else -- If not, use the unknown map icon
		print(map.." does not have a Gametracker image!")
	end
end,
function (error)
	print("[Error] Could not fetch image bool for: "..map)
end)

print(MapImgUrl)




<?php
	// PHP function to check 404 of map images by Tomelyr (STEAM_0:0:9136467)
	function MapImgExists($url){
		$ch = curl_init($url);    
		curl_setopt($ch, CURLOPT_NOBODY, true);
		curl_exec($ch);
		$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		
		if($code == 200) {
			$exists = 'true';
		} else {
            $exists = 'false';
		}
		curl_close($ch);
		return $exists;
    }
    
	if (isset($_GET["url"])) {
		$real = 'nope';
		$mapurl = $_GET['url'];
		$real = MapImgExists($mapurl);
		echo $real;
	}
?>


[editline]6th December 2014[/editline]

GM/PostDrawOpaqueRenderables


 
local developer = GetConVar( "developer" )

function printf( s, ... )
 print( s:format( ... ) )
end

function dprintf( ... )
 if developer:GetBool( ) then
  printf(...)
 end
end

function assert2( b, msg )
 if not b then
  error( msg, 2 )
 end
end

function InSet( v, ... )
 for k, j in pairs{ ... } do
  if v == j then
   return true
  end
 end
 return false
end

function SetMulti( key, value, ... )
  for k, v in pairs{ ... } do
   v[ key ] = value
  end
end

local function subset( data, start, endp )
 local t = { }

 for k=start, endp do
  t[ #t + 1 ] = data[ k ]
 end

 return unpack( t )
end

function foreachm( key, argc, ... )
  local t = { ... }
  
  for k = argc + 1, #t do
   t[ k ][ key ]( t[ k ], subset( t, 1, argc ) )
  end
end


Typed from memory, so caveat coder and so on.

I liked the idea of that since I think the surface library takes up too much code, so I took the idea and made a lua module for it. I have no idea if it works or anything but maybe someone will find the code in here useful

[lua]
----// Simplified Surface Module //----

module( “surface2”, package.seeall )

function DrawRect( x, y, width, height, color )

surface.SetDrawColor( color )
surface.DrawRect( x, y, width, height )

end

function DrawText( text, font, x, y, color )

surface.SetFont( font )
surface.SetTextColor( color )
surface.SetTextPos( x, y ) 
surface.DrawText( text )

end

function DrawTexturedRect( x, y, width, height, texture, color )

if type(texture) == "IMaterial" then
	surface.SetMaterial(texture)
else
	surface.SetTexture( texture )
end

surface.SetDrawColor( color )
surface.DrawTexturedRect( x, y, width, height )

end

function DrawTexturedRectRotated( x, y, width, height, texture, rotation, color )

if type(texture) == "IMaterial" then
	surface.SetMaterial(texture)
else
	surface.SetTexture( texture )
end

surface.SetDrawColor( color )
surface.DrawTexturedRectRotated( x, y, width, height, rotation )

end

function DrawTexturedRectUV( x, y, width, height, texture, color, startU, startV, endU, endV )

if type(texture) == "IMaterial" then
	surface.SetMaterial(texture)
else
	surface.SetTexture( texture )
end

surface.SetDrawColor( color )
surface.DrawTexturedRectUV( x, y, width, height, startU, startV, endU, endV )

end

function DrawPoly( color, vertices )

surface.SetDrawColor( color )
surface.DrawPoly( vertices )

end

function DrawOutlinedRect( x, y, width, height, color )

surface.SetDrawColor( color )
surface.DrawRect( x, y, width, height )

end

function DrawLine( startx, starty, endx, endy, color )

surface.SetDrawColor( color )
surface.DrawLine( startx, stary, endx, endy )

end

function DrawCircle( x, y, radius, color )

surface.SetDrawColor( color )
surface.DrawCircle( x, y, radius, color )

end
[/lua]

Draw a sector of a circle with a specified angle and rotation
useful for radial huds (?)



function surface.DrawSector(x, y, r, ang, rot)

	local segments = 360
	local segmentstodraw = 360 * (ang/360)
	rot = rot* (segments/360)
	local poly = {}

	local temp = {}
	temp['x'] = x
	temp['y'] = y
	table.insert(poly, temp)

	for i = 1+rot, segmentstodraw+rot do
		local temp = {}
		temp['x'] = math.cos( (i*(360/segments) )*(math.pi/180) ) * r + x
		temp['y'] = math.sin( (i*(360/segments) )*(math.pi/180) ) * r + y

		table.insert(poly, temp)
	end
	
	surface.DrawPoly(poly)

end


you can change the segments variable to something smaller if you don’t need all those points in the surface.DrawPoly table, e.g 90 segments or 180 segments will still look circular (i dont actually know if changing segments will work, i wrote this a long time ago and have always used 360)

smooth health changing:

local smooth = 0

… inside your hook…

local hp = ply:Health()
smooth = math.Approach( smooth, hp, 50 * RealTime() )


function HeadText (ply)
local BoneIndx = ply:LookupBone("ValveBiped.Bip01_Head1")
local BonePos, BoneAng = ply:GetBonePosition( BoneIndx )
local pos = BonePos + Vector(0,0,80) -- Place above head bone
local eyeang = LocalPlayer():EyeAngles().y - 90 -- Face upwards
local ang = Angle( 0, eyeang, 90 )

-- Start drawing 
cam.Start3D2D(pos, ang, 0.1)
	draw.DrawText( ply:Nick(), "Trebuchet24", 0, 400, Color(0,0,0), TEXT_ALIGN_CENTER )
cam.End3D2D()
end) 
hook.Add("PostDrawOpaqueRenderables", "3d2d text", HeadText)



I dont think the 3d/2d text above players head works because I get this:


[ERROR] gamemodes/war/gamemode/modules/headtext/cl_head_text.lua:4: attempt to index local 'ply' (a boolean value)
  1. v - gamemodes/war/gamemode/modules/headtext/cl_head_text.lua:4
   2. unknown - lua/includes/modules/hook.lua:84