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.