hats!

I found this script to add a hat to players.
Only problem is it is super glitchy. Sometimes the hats don’t spawn. When they do they are pink colored. They are also supposed to be invisible to the player but they are not.

Now I am not an lua expert by far but this just seems like bad code. I am thinking of trying to rewrite it with hooks instead of timers and think.
If there is any obvious glaring reason why this code is buggy then please let me know.

init.lua
[LUA]
AddCSLuaFile(“cl_init.lua”)
AddCSLuaFile(“shared.lua”)

include(‘shared.lua’)

function SpawnSantaFunction( pl )

    local headcrabs , m = ents.FindByClass( "santa" )
    for _ , m in pairs( headcrabs ) do
            if ( m && m:IsValid( ) && m:GetOwner( ) == pl ) then
                    return
            end
    end


    local eyes = pl:LookupAttachment( "eyes" )

    if ( eyes == 0 ) then return end


    santa = ents.Create( 'santa' )


    santa:SetOwner( pl )
    santa:SetParent( pl )
    santa:SetModel("models/santa/santa.mdl")

    santa:SetPos(pl:EyePos())

    santa:Spawn( )
    santa:Activate( )


    santa:SetMoveType( MOVETYPE_NONE )
    santa:SetSolid( SOLID_NONE )
    santa:SetCollisionGroup( COLLISION_GROUP_NONE )
    santa:DrawShadow( false )



    return santa

end

function SpawnHats( ply )
timer.Create( “timer_hat”…ply:UniqueID(), 1, 1, function()
SpawnSantaFunction( ply )
end )
end
hook.Add( “PlayerSpawn”, “SpawnHats”, SpawnHats )

function SetString()
for k, v in pairs( player.GetAll() ) do
v:SetNWString( “PModel”, v:GetModel() )
end
end
hook.Add( “Think”, “SetString”, SetString )

[/LUA]

cl_init.lua - full code http://pastebin.com/Vy09fjQV
[LUA]
include(“shared.lua”)

function ENT:Think()
if not self:GetOwner():Alive() then
self:SetColor( Color(0,0,0,0) )
self:SetRenderMode( RENDERMODE_TRANSALPHA )
return
else
if self:GetOwner():GetNWString( “PModel” ) == “models/player/zombiefast.mdl” || self:GetOwner():GetNWString( “PModel” ) == “models/player/classic.mdl” then
self:SetColor( Color(0,0,0,0) )
self:SetRenderMode( RENDERMODE_TRANSALPHA )
else
if LocalPlayer() == self:GetOwner() then
self:SetColor( Color(0,0,0,0) )
self:SetRenderMode( RENDERMODE_TRANSALPHA )
else
self:SetColor( Color(255,255,255,255) )
end
end
end

NextTime = 1
if ( CurTime() >= NextTime && !self:GetOwner():Alive() ) then
self:DrawModel()
NextTime = CurTime() + 1
end

end

function ENT:Draw()
local owner = self:GetOwner()

    if owner:GetRagdollEntity() then
            owner = owner:GetRagdollEntity()
    elseif not owner:Alive() then self:SetNoDraw( true ) end

    local boneindex = owner:LookupBone("ValveBiped.Bip01_Head1")
    if boneindex then
            local pos, ang = owner:GetBonePosition(boneindex)
            if pos and pos ~= owner:GetPos() then
                    if owner:GetNWString( "PModel" ) == "models/player/group01/female_06.mdl" then
                            self.Entity:SetPos(pos + ang:Forward()*1 + ang:Right()*-1.3)

                    --A BUNCH OF elseif's to set various models positions

                     end

                    ang:RotateAroundAxis(ang:Right(),-90)
                    ang:RotateAroundAxis(ang:Up(),270)
                    self:SetAngles(ang)
                    if LocalPlayer() == self:GetOwner() then
                            self:SetColor( Color(0,0,0,0) )
                            self:SetRenderMode( RENDERMODE_TRANSALPHA )
                    else
                            self:SetColor( Color(255,255,255,255) )
                    end
                    self:DrawModel()
                    return
            end

    local attach = owner:GetAttachment(owner:LookupAttachment("eyes"))
    if not attach then attach = owner:GetAttachment(owner:LookupAttachment("head")) end
    if attach then
            self:SetPos(attach.Pos)
            self:SetAngles(attach.Ang)
            //self:DrawModel()
    end
    end

end
[/LUA]

shared.lua
[LUA]
ENT.Type = “anim”
ENT.Base = “base_anim”
ENT.PrintName = “Shane’s Santa Hat”
ENT.Author = “Shane”
ENT.Category = “Hats”

ENT.Spawnable = false
ENT.AdminSpawnable = false
[/LUA]

Stop using self.Entity, and change all self:SetColor(r, g, b, a) to self:SetColor( Color(r, g, b, a) )

Instead of self.Entity what should it be?

self

all right so the color problem is fixed but the hats still are not being set on everyone and they are not invisible for the player

you didn’t set the position of the entity server-side. Set it to the player:EyePos()
It’s probably spawning in the void and not getting updated on the client.

I was literally about to do this myself!

If you would be so kind to post the finished lua i would love you forever <3

If I can figure this out before garry locks this thread then sure.

I already updated the orginal post with the changes and put a link to pastebin for the full code of cl_init.lua with all the if else’s for the model offsets.

Figured out the invisibility problem. Needed to set self:SetRenderMode( RENDERMODE_TRANSALPHA )

Now I just need to figure out why it doesn’t spawn for everyone all the time.

updated code… it is now working. thanks for the help.

Still have one last bug. It isn’t game breaking but causes script errors only some of the time. It isn’t constant errors so I have discovered the circumstances that cause the error.



[ERROR] lua/entities/santa/cl_init.lua:4: attempt to call method 'Alive' (a nil value)
  1. unknown - lua/entities/santa/cl_init.lua:4


Not sure what causes it… I think maybe the owner is disconnected so it comes back nil and nil:Alive() is nil???

How would I put in a check to make sure a function exists… or is there some other code problem I am missing?"

[lua]if not self:GetOwner():IsValid() then return end[/lua]
Before line 4 in cl_init.lua