Common Code Snippets Misc
From GMod Wiki
Contents |
Tracing a Line
This traces a line from the player's shoot position in the direction that they're facing. The result is tr which contains a trace result table.
local vStart = my_player_object:GetShootPos() local vForward = my_player_object:GetAimVector() local trace = {} trace.start = vStart trace.endpos = vStart + (vForward * 2048) trace.filter = my_player_object local tr = util.TraceLine( trace )
Quick Trace
local trace = my_player_object:GetEyeTrace() local hitpos = trace.HitPos
Quick Trace 2
local trace = util.QuickTrace( my_player_object:GetShootPos(), my_player_object:GetAimVector(), my_player_object ) local hitpos = trace.HitPos
See util.QuickTrace.
Calling a Function on the Client Gamemode
You shouldn't be calling this a lot. Once every few seconds is fine, but this passes a string over the network - which can cause quite a bit of lag if you're careless with it.
local filter = RecipientFilter() filter:AddAllPlayers() gmod.ClientCallGamemode( filter, "SetTurn", self.CurrentPlayer:EntIndex() .." ".. self.TurnTime);
Printing a Message to a Player
This prints to the talk area. Where 'ply' is a player object. (See player.PrintMessage for more information)
ply:PrintMessage( HUD_PRINTTALK, "This is a message" )
Alternatively, you can also just use PrintMessage to print a message to all players:
PrintMessage( HUD_PRINTTALK, "Welcome everyone, enjoy your stay!" )
Generating Random Messages
local randommessages = { "Hello.", "Hi there.", "How's it going?", "Hai thar mang!" //etc... } local rndmsg = math.random(1, table.Count(randommessages)) //Random number between 1, and the number of items in the table print(randommessages[rndmsg])
This also works for sound and models:
local Sounds = { Sound("path to sound"), Sound("Another path to sound"), Sound("Another one") } local rndmsnd = math.random(1, #Sounds) local randomSound = (Sounds[rndmsnd])
Alternative method:
local randommessages = { "Hello.", "Hi there.", "How's it going?", "Hai thar mang!" //etc... } print( table.Random( randommessages ) ) --Uses table.Random, saves some space
Spectate from ragdoll eyes
While dead changes your eye position to the ragdolls eyes making you see whatever the ragdoll sees
//We're doing this in the gamemode hook for now function GM:CalcView(ply,pos,ang,fov) //Get the ragdoll entity of the player //This will return nil if the player is alive local rag = ply:GetRagdollEntity() //If the entity is valid if ValidEntity(rag) then //Get the eye attachment from the ragdoll local att = rag:GetAttachment(rag:LookupAttachment("eyes")) //Don't return a self made table here, return the table returned by the base function return self.BaseClass:CalcView(ply,att.Pos,att.Ang,fov) //If not in a gamemode then use this //return GAMEMODE:CalcView(ply,att.Pos,att.Ang,fov) end //Else return what is received, which means don't change anything return self.BaseClass:CalcView(ply,pos,ang,fov) end
Disable jumping on your server
Put this script in lua/autorun/nojump.lua and clients won't be able to jump on your server. Also useful for gamemodes I guess.
if CLIENT then --Prevents clients from calling the +jump console command, but doesn't remove it function BlockJump( ply, bind ) if string.find(bind, "+jump") then return true end end hook.Add( "PlayerBindPress", "BlockJump", BlockJump ) else --Send file to clients AddCSLuaFile( "autorun/nojump.lua" ) --Also set their jump power to 0, so they can't get around the above code by typing +jump in the console function BlockJump( ply ) ply:SetJumpPower( 0 ) end hook.Add( "PlayerInitialSpawn", "BlockJump", BlockJump ) end
XKillerBoy:
You can also add it to lua\autorun\server without the bind blocking.
function BlockJump( ply ) ply:SetJumpPower( 0 ) end hook.Add( "PlayerInitialSpawn", "BlockJump", BlockJump )
Disabling the GravGun's Punt
This will prevent a player from hauling objects across the room, using the least amount of code.
hook.Add("GravGunPunt", "DontPunt", function(Pl, Ent) DropEntityIfHeld(Ent) return false end)
Screen to Vector / Vector to Screen with custom screen / camera
Written by theJ89 09:48, 24 October 2011 (PDT)
Original thread: http://www.facepunch.com/threads/891702
--[[ Give this function the coordinates of a pixel on your screen, and it will return a unit vector pointing in the direction that the camera would project that pixel in. Useful for converting mouse positions to aim vectors for traces. iScreenX is the x position of your cursor on the screen, in pixels. iScreenY is the y position of your cursor on the screen, in pixels. iScreenW is the width of the screen, in pixels. iScreenH is the height of the screen, in pixels. angCamRot is the angle your camera is at fFoV is the Field of View (FOV) of your camera in ___radians___ Note: This must be nonzero or you will get a divide by zero error. ]]-- function LPCameraScreenToVector( iScreenX, iScreenY, iScreenW, iScreenH, angCamRot, fFoV ) --This code works by basically treating the camera like a frustrum of a pyramid. --We slice this frustrum at a distance "d" from the camera, where the slice will be a rectangle whose width equals the "4:3" width corresponding to the given screen height. local d = 4 * iScreenH / ( 6 * math.tan( 0.5 * fFoV ) ) ; --Forward, right, and up vectors (need these to convert from local to world coordinates local vForward = angCamRot:Forward(); local vRight = angCamRot:Right(); local vUp = angCamRot:Up(); --Then convert vec to proper world coordinates and return it return ( d * vForward + ( iScreenX - 0.5 * iScreenW ) * vRight + ( 0.5 * iScreenH - iScreenY ) * vUp ):Normalize(); end --[[ Give this function a vector, pointing from the camera to a position in the world, and it will return the coordinates of a pixel on your screen - this is where the world position would be projected onto your screen. Useful for finding where things in the world are on your screen (if they are at all). vDir is a direction vector pointing from the camera to a position in the world iScreenW is the width of the screen, in pixels. iScreenH is the height of the screen, in pixels. angCamRot is the angle your camera is at fFoV is the Field of View (FOV) of your camera in ___radians___ Note: This must be nonzero or you will get a divide by zero error. Returns x, y, iVisibility. x and y are screen coordinates. iVisibility will be: 1 if the point is visible 0 if the point is in front of the camera, but is not visible -1 if the point is behind the camera ]]-- function VectorToLPCameraScreen( vDir, iScreenW, iScreenH, angCamRot, fFoV ) --Same as we did above, we found distance the camera to a rectangular slice of the camera's frustrum, whose width equals the "4:3" width corresponding to the given screen height. local d = 4 * iScreenH / ( 6 * math.tan( 0.5 * fFoV ) ); local fdp = angCamRot:Forward():Dot( vDir ); --fdp must be nonzero ( in other words, vDir must not be perpendicular to angCamRot:Forward() ) --or we will get a divide by zero error when calculating vProj below. if fdp == 0 then return 0, 0, -1 end --Using linear projection, project this vector onto the plane of the slice local vProj = ( d / fdp ) * vDir; --Dotting the projected vector onto the right and up vectors gives us screen positions relative to the center of the screen. --We add half-widths / half-heights to these coordinates to give us screen positions relative to the upper-left corner of the screen. --We have to subtract from the "up" instead of adding, since screen coordinates decrease as they go upwards. local x = 0.5 * iScreenW + angCamRot:Right():Dot( vProj ); local y = 0.5 * iScreenH - angCamRot:Up():Dot( vProj ); --Lastly we have to ensure these screen positions are actually on the screen. local iVisibility if fdp < 0 then --Simple check to see if the object is in front of the camera iVisibility = -1; elseif x < 0 || x > iScreenW || y < 0 || y > iScreenH then --We've already determined the object is in front of us, but it may be lurking just outside our field of vision. iVisibility = 0; else iVisibility = 1; end return x, y, iVisibility; end