User:MadDog986
From GMod Wiki
Welcome
Welcome to my page. I am going to use this page to mainly leave notes for myself and code snippets that i could use in the future.
If you see a coding error or a better way to code it, please help me improve! I have only been doing LUA since May 2008!
Basic Entity template
init.lua
AddCSLuaFile( 'cl_init.lua' ) AddCSLuaFile( 'shared.lua' ) include( 'shared.lua' ) //required to spawn function ENT:SpawnFunction( ply, tr ) if not tr.Hit then return end local ent = ents.Create( self.Classname ) ent:SetPos( tr.HitPos + tr.HitNormal * 24 ) ent:Spawn() ent:Activate() return ent end //Initialize function ENT:Initialize() //self.BaseClass.Initialize(self) self:SetModel( "models/Combine_Helicopter/helicopter_bomb01.mdl" ) self.Entity:PhysicsInit( SOLID_VPHYSICS ) self.Entity:SetMoveType( MOVETYPE_VPHYSICS ) self.Entity:SetSolid( SOLID_VPHYSICS ) local phys = self:GetPhysicsObject() if phys:IsValid() then phys:Wake() end end //updates every frame function ENT:Think() //self.BaseClass.Think(self) //give new title... useful for interactive entities //self:SetTitle("New Title") //self.Entity:NextThink( CurTime() + 1 ) //return true end /*Additional functions function ENT:AcceptInput( name ) end function ENT:EndTouch( ent ) end function ENT:KeyValue( key, value ) end function ENT:OnTakeDamage( dmginfo ) end function ENT:OnRemove() end function ENT:OnRestore() end function ENT:PhysicsCollide( physobj ) end function ENT:PhysicsSimulate( phys, deltatime ) end function ENT:PhysicsUpdate( phys ) end function ENT:StartTouch( ent ) end function ENT:Touch( entity ) end function ENT:UpdateTransmitState() end function ENT:Use( activator, caller ) end */
cl_init.lua
include("shared.lua") //Creates the ent draw function ENT:Draw() self.Entity:DrawModel() //Draw the model //if player within distance show title if ( LocalPlayer():GetEyeTrace().Entity == self.Entity && EyePos():Distance( self.Entity:GetPos() ) < 512 ) then //add the title AddWorldTip( self.Entity:EntIndex(), self:GetTitle(), 0.5, self.Entity:GetPos(), self.Entity ) end end /*Additional functions function ENT:Think() end function ENT:IsTranslucent() end function ENT:OnRemove() end function ENT:OnRestore() end function ENT:PhysicsCollide( physobj ) end function ENT:PhysicsUpdate( phys ) end */
shared.lua
ENT.Type = "anim" ENT.Base = "base_gmodentity" //The name of my Entity ENT.PrintName = "md_base" //Ents name. ENT.Author = "MadDog" ENT.Contact = "Don't" ENT.Purpose = "Base Entity" //What the ents purpose is. ENT.Spawnable = false //Spawnable by anyone. ENT.AdminSpawnable = false //spawnable by admins. //set title function ENT:SetTitle(title) self.Entity:SetNWString("Title", title) end //get title function ENT:GetTitle() //try to get title local title = self.Entity:GetNWString("Title") //if no title then get it from the Printname if (!title) then title = self.PrintName end //return the title return title end
User Message
This go on the clientside.
//sends a message to a user function MD_SendMessage(Message, Type) local Sound = "ambient/water/drip2.wav" //select sound type if (Type == 1) then Sound = "buttons/button10.wav" elseif (Type == 2) then Sound = "buttons/button17.wav" elseif (Type == 3) then Sound = "buttons/bell1.wav" elseif (Type == 4) then Sound = "ambient/machines/slicer"..math.random(1, 4)..".wav" end GAMEMODE:AddNotify(Message, Type, 10) surface.PlaySound(Sound) end
Something i would use this for is when someone joins and i want to send them a little message:
(clientside)
//add a rules warning (but wait 15 seconds) timer.Simple(15, function() MD_SendMessage('You better have read the rules! Type in chat box: !motd', 4) end)
- or -
(serverside)
//send from server: player:SendLua("MD_SendMessage('message', 1)")
Cool Little Blowup Effect
function ENT:OnRemove() //explode on remove //local vars local size, pos = self:BoundingRadius(), self:GetPos() //set explode effect (fire flash) local Effect = EffectData() Effect:SetOrigin(pos) Effect:SetScale(size) Effect:SetRadius(size) Effect:SetMagnitude(size) util.Effect("HelicopterMegaBomb", Effect) //2nd effect, smoke, some gibs, and sound util.Effect("Explosion", Effect) end
Preload sounds from list
//preload sounds local preloadSounds = {"ambient/water/drip2.wav","buttons/button10.wav","buttons/button17.wav","buttons/bell1.wav","ambient/machines/slicer1.wav","ambient/machines/slicer2.wav","ambient/machines/slicer3.wav","ambient/machines/slicer4.wav"} //loop through and preload sounds for i=1, #preloadSounds do util.PrecacheSound(preloadSounds[i]) end
ent:IsMoving()
//returns true if moving, false otherwise function ENT:IsMoving() local phys = self:GetPhysicsObject() if !phys:IsValid() then return false end if phys:GetVelocity():Length() > 0 or phys:GetAngleVelocity():Length() > 0 then return true else return false end end
Get player Armor on clientside
This was added to Player.Armor
serverside:
hook.Add("PlayerSpawn", "ArmorSet", function(ply) ply:SetNWInt("Armor", ply:Armor() end) hook.Add("EntityTakeDamage", "ArmorUpdate", function(ent, inflictor, attacker, amount, dmginfo) if !ent:IsPlayer() then return end ent:SetNWInt("Armor", ent:Armor()) end)
clientside:
local client = LocalPlayer() Msg("My Armor is: " .. tostring(client:GetNWInt("Armor")))
Entity Water Depth
Untested (i will test later).
function EntityWaterDepth( ent ) local Start = ent:LocalToWorld( ent:OBBCenter() ) local End = ent:GetPos() + Vector( 0, 0, 16384 ) local tr = util.TraceLine( { start = Start, endpos = End, filter = ent, mask = MASK_SOLID_BRUSHONLY } ) if tr.Hit then tr = util.TraceLine( { start = tr.HitPos, endpos = Start, filter = ent, mask = MASK_WATER } ) if tr.Hit then return math.Clamp( tr.HitPos.z - Start.z, 0, 16384 ) end end return 0 end
Check if sky is above player
p = FindMetaTable("Player") function p:IsOutdoors() -- Perform the trace local tr = {} tr.start = self:GetPos() tr.endpos = self:GetPos() + Vector(0, 0, 100000) tr.filter = self local trace = util.TraceLine(tr) -- Return result return trace.HitSky end
Explode with force
local entity = ents.Create( "env_physexplosion" ) if( !IsValid( entity ) ) then return end entity:SetPos( vector_origin ) entity:SetKeyValue( "magnitude", 50 ) entity:SetKeyValue( "spawnflags", 1 ) entity:Spawn( ) entity:Activate( ) entity:Fire( "Explode", "", 0 ) entity:Fire( "Kill", "", 0.5 )
TranslateVelocity
"This translates the velocity of an entity (object) when it hits the event horizon of a portal (entrance) to that of the entity when it emerges from the event horizon of the other portal (exit)." thanks thomasfn
local function TranslateVelocity( entrance, exit, object ) // Get the phys obj local phys = object:GetPhysicsObject() if not (phys && phys:IsValid()) then return end // Get the current velocity local vel = phys:GetVelocity() // Convert it to an angle and length local ang = vel:Angle() local len = vel:Length() // Translate the angle local newang = ang + (exit:GetAngles() - entrance:GetAngles()) // Construct the new vector local newvel = newang:Forward() * len // Return the result return newvel end
Prop grow in size
local SHeight = 5; local SWidth = 2.5 local MaxHeight = 25; local MaxWidth = 15; function ENT:Draw() local GrowthPercent = (CurTime() - self.SpawnTime) / self.GrowthTime; if GrowthPercent <= 1 then local W = SWidth + (GrowthPercent * MaxWidth ); self:SetModelScale(.05 * Vector(W, W, SHeight + (GrowthPercent * MaxHeight))); end self:DrawModel(); end // credits too hunts
Wire: Inputs & Outputs made easy
Here is a script i wrote up for a script im working on. It makes inputs and outputs for wire easier to handle.
local meta = FindMetaTable( "Entity" ) function meta:WireInput( name ) if (!WireAddon) then return end self.WireDebugName = (self.PrintName or "Unknown") if (!self.WireInputs) then self.WireInputs = {name} self.Inputs = Wire_CreateInputs( self, self.WireInputs ) elseif (!table.HasValue( self.WireInputs, name)) then table.insert( self.WireInputs, name ) table.sort(self.WireOutputs) --add new input Wire_AdjustInputs( self, self.WireInputs ) end end function meta:WireOutput( name ) if (!WireAddon) then return end self.WireDebugName = (self.PrintName or "Unknown") if (!self.WireOutputs) then self.WireOutputs = {name} self.Outputs = Wire_CreateOutputs( self, self.WireOutputs ) elseif (!table.HasValue( self.WireOutputs, name)) then table.insert( self.WireOutputs, name ) table.sort(self.WireOutputs) --add new output Wire_AdjustOutputs( self, self.WireOutputs ) end end function meta:WireUpdate( name, value ) if (!WireAddon) then return end --make sure output exists if (!table.HasValue( self.WireOutputs or {}, name)) then self:WireOutput( name ) end --update output Wire_TriggerOutput( self, name, value ) end
Admin Teleport Command
concommand.Add( "md_teleport", function( player, command ) if ( !GAMEMODE.IsSandboxDerived ) then return end if ( !player:IsAdmin() ) then return end player:SetPos( player:GetEyeTrace().HitPos + Vector(0,0,40) ); end )