[Lua] Bone Merged Models Cause Memory Leaks

I’m having some problems with bone merging a prop to a player model and removing it. When I attach it it causes memory leaking until the frame rate drops to 1.

Here’s the code I’m using:

[lua]
local function MaskToggle()
if CLIENT then
local MaskMDL = ClientsideModel( “models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl”, RENDERGROUP_BOTH)
if self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == true then
MaskMDL:SetParent(self.Owner)
MaskMDL:AddEffects(EF_BONEMERGE)
if self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == false then
MaskMDL:Remove()
end
end
end
[/lua]

Am I doing this correctly? The wiki isn’t very detailed on how to do bone merged models so I’m running off what I see in an add-on I have downloaded.

ClientsideModel() creates a new clientside model everytime, you should assign a variable to the owner.



self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( "models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl", RENDERGROUP_BOTH)

local MaskMDL = self.Owner.MaskMDL


EDIT: also, saw a syntax error in your code, after every



if ( blah ) then

end


OR



if ( blah ) then

elseif ( blah ) then

end


OR



if ( blah ) then

else

end


NOT



if ( blah ) then

if ( blah ) then


That didn’t work, now it’s complaining about SetParent not being valid.


[ERROR] addons/stalker_gasmask_sent/lua/weapons/stalker_gas_mask_sunrise.lua:107: Tried to use a NULL entity!
  1. SetParent - [C]:-1
   2. SunriseMaskToggle - addons/stalker_gasmask_sent/lua/weapons/stalker_gas_mask_sunrise.lua:107
    3. unknown - addons/stalker_gasmask_sent/lua/weapons/stalker_gas_mask_sunrise.lua:79


Here’s the full code I’m using:

[lua]

function SWEP:Think()
if self.Owner:KeyPressed(IN_RELOAD) and ActionDelay <= CurTime() then
local MaskMDL = self.Owner.MaskMDL
if self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == false then
if CLIENT then
self.Owner:ViewPunch(Angle(-35,0,0))
surface.PlaySound( “jessev92/items/gas_mask_on.wav” )
RunConsoleCommand( “pp_mat_overlay”, “jessev92/ui/overlays/mask_gas01” )
self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( “models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl”, RENDERGROUP_BOTH)
MaskMDL:SetParent(self.Owner)
MaskMDL:AddEffects(EF_BONEMERGE)
end
if SERVER then
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, true )
end
ActionDelay = CurTime() + 3
elseif self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == true then
if CLIENT then
self.Owner:ViewPunch(Angle(-35,0,0))
surface.PlaySound( “jessev92/items/gas_mask_off.wav” )
RunConsoleCommand( “pp_mat_overlay”, “” )
MaskMDL:Remove()
end
if SERVER then
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, false )
end
ActionDelay = CurTime() + 3
end
end
end

[/lua]

I’m not sure why the code is giving an error for SetParent now when it worked before. The memory leaks are gone but the mask doesn’t appear now.

that self.Owner.MaskMDL = blah has to be set before the local MaskMDL




function SWEP:Think()
	if self.Owner:KeyPressed(IN_RELOAD) and ActionDelay <= CurTime() then
                		self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( "models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl", RENDERGROUP_BOTH)
		local MaskMDL = self.Owner.MaskMDL	
		if self.Owner:GetNWBool( "STALKER_PlyGasMaskOn" ) == false then
			if CLIENT then
				self.Owner:ViewPunch(Angle(-35,0,0))
				surface.PlaySound( "jessev92/items/gas_mask_on.wav" )
				RunConsoleCommand( "pp_mat_overlay", "jessev92/ui/overlays/mask_gas01" )	
				MaskMDL:SetParent(self.Owner)
				MaskMDL:AddEffects(EF_BONEMERGE)
			end
			if SERVER then
				self.Owner:SetNWBool( "STALKER_PlyGasMaskOn", true )
			end
			ActionDelay = CurTime() + 3
		elseif self.Owner:GetNWBool( "STALKER_PlyGasMaskOn" ) == true then
			if CLIENT then
				self.Owner:ViewPunch(Angle(-35,0,0))
				surface.PlaySound( "jessev92/items/gas_mask_off.wav" )
				RunConsoleCommand( "pp_mat_overlay", "" )
				MaskMDL:Remove()
			end
			if SERVER then
				self.Owner:SetNWBool( "STALKER_PlyGasMaskOn", false )
			end
			ActionDelay = CurTime() + 3
		end
	end
end


When I put that in it will complain about the ClientsideModel line not being on the client, so I put that line into an if CLIENT then block and it’s still complaining about SetParent.

Ah, you are right, because ClientsideModel is a client function.



function SWEP:Think()
	if self.Owner:KeyPressed(IN_RELOAD) and ActionDelay <= CurTime() then
		if self.Owner:GetNWBool( "STALKER_PlyGasMaskOn" ) == false then
			if CLIENT then
	self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( "models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl", RENDERGROUP_BOTH)
		local MaskMDL = self.Owner.MaskMDL	

				self.Owner:ViewPunch(Angle(-35,0,0))
				surface.PlaySound( "jessev92/items/gas_mask_on.wav" )
				RunConsoleCommand( "pp_mat_overlay", "jessev92/ui/overlays/mask_gas01" )	
				MaskMDL:SetParent(self.Owner)
				MaskMDL:AddEffects(EF_BONEMERGE)
			end
			if SERVER then
				self.Owner:SetNWBool( "STALKER_PlyGasMaskOn", true )
			end
			ActionDelay = CurTime() + 3
		elseif self.Owner:GetNWBool( "STALKER_PlyGasMaskOn" ) == true then
			if CLIENT then
				self.Owner:ViewPunch(Angle(-35,0,0))
				surface.PlaySound( "jessev92/items/gas_mask_off.wav" )
				RunConsoleCommand( "pp_mat_overlay", "" )
				MaskMDL:Remove()
			end
			if SERVER then
				self.Owner:SetNWBool( "STALKER_PlyGasMaskOn", false )
			end
			ActionDelay = CurTime() + 3
		end
	end


Same error. This is what the current code looks like:

[lua]
function SWEP:Think()
if self.Owner:KeyPressed(IN_RELOAD) and ActionDelay <= CurTime() then
local MaskMDL = self.Owner.MaskMDL
if self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == false then
if CLIENT then
self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( “models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl”, RENDERGROUP_BOTH)
self.Owner:ViewPunch(Angle(-35,0,0))
surface.PlaySound( “jessev92/items/gas_mask_on.wav” )
RunConsoleCommand( “pp_mat_overlay”, “jessev92/ui/overlays/mask_gas01” )
MaskMDL:SetParent(self.Owner)
MaskMDL:AddEffects(EF_BONEMERGE)
end
if SERVER then
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, true )
end
ActionDelay = CurTime() + 3
elseif self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == true then
if CLIENT then
self.Owner:ViewPunch(Angle(-35,0,0))
surface.PlaySound( “jessev92/items/gas_mask_off.wav” )
RunConsoleCommand( “pp_mat_overlay”, “” )
MaskMDL:Remove()
end
if SERVER then
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, false )
end
ActionDelay = CurTime() + 3
end
end
end

[/lua]

Is SetParent able to be run on client? It says it’s shared on the wiki so it should be able to. It’s complaining about the player (self.Owner) not being valid on the client.

[editline]22nd February 2016[/editline]

Okay so I’ve got it all working except the parenting. I don’t think SetParent likes me passing it self.Owner as the parent to attach to.

Okay, I figured it out. Here’s the final code:

[lua]
function SWEP:Think()
if self.Owner:KeyPressed(IN_RELOAD) and ActionDelay <= CurTime() then
if self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == false then
if CLIENT then
self.Owner.MaskMDL = ClientsideModel( “models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl”, RENDERGROUP_BOTH)
local MaskMDL = self.Owner.MaskMDL
MaskMDL:SetParent( self.Owner )
MaskMDL:AddEffects(EF_BONEMERGE)
surface.PlaySound( “jessev92/items/gas_mask_on.wav” )
RunConsoleCommand( “pp_mat_overlay”, “jessev92/ui/overlays/mask_gas01” )
end
if SERVER then
self.Owner:ViewPunch(Angle(35,0,0))
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, true )
end
elseif self.Owner:GetNWBool( “STALKER_PlyGasMaskOn” ) == true then
if CLIENT then
surface.PlaySound( “jessev92/items/gas_mask_off.wav” )
RunConsoleCommand( “pp_mat_overlay”, “” )
self.Owner.MaskMDL = self.Owner.MaskMDL or ClientsideModel( “models/jessev92/stalker/items/devices/gas_mask_sunrise_w.mdl”, RENDERGROUP_BOTH)
local MaskMDL = self.Owner.MaskMDL
MaskMDL:Remove()
end
if SERVER then
self.Owner:ViewPunch(Angle(35,0,0))
self.Owner:SetNWBool( “STALKER_PlyGasMaskOn”, false )
end
end
ActionDelay = CurTime() + 3
end
end
[/lua]