Help with TakeDamage being a nil value

Hey guys, I’m fixing up an old gamemode called Cube 2.2 and it all works perfectly fine, apart from a suicide gun which is part of the game. When you have the gun, you kill yourself fine, but there’s a lua error regardless after you’ve died, about TakeDamage being a nil value. The original function this part of the swep was using was SWEP:Shoot, which didn’t allow the gun to fire and caused self in the first self.Owner line to be a nil value, but after some research I learnt why this was and changed it to Think. If this is incorrect, do let me know since I haven’t worked with SWEPs much.

Below is the error and code. I try to avoid making threads like this, but I’ve been reading through a lot of old Facepunch threads and Wiki pages, however none of them have really helped. I have been playing around with the code and changed various things I thought might work, but none of them have. If any of you guys could point out what I’m doing wrong or head me in the right direction, it would be greatly appreciated.


function SWEP:Think()
	
	local pos = self.Owner:GetPos();
	
	sound.Play( self.ShootSound, self:GetPos() ); -- So the sound doesn't cut after I die
	
	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK );
	
	self.Owner:TakeDamage( 200, self, self ); // this line
	
end



function SWEP:PrimaryAttack()
     if ( !self.Owner:IsValid() or !self.Owner:Alive() ) then return end -- Let's make sure they are valid and alive before we go around breaking things.
     self.Owner:TakeDamage ( 200, self, self)
end

I think what happens is it is a think function, and after the player dies it keeps running. but self.Owner is no longer alive after they die, so it cannot use TakeDamage anymore, triggering the error AFTER they die, because it ran fine the first time.

I don’t think you should have to use a think function, I would just try to hook the SWEP:PrimaryAttack() instead.
I think your problem is Swep:Shoot() no longer exists.

Well, here’s the whole SWEP code, if it helps.This is a server with multiple gamemodes and some stuff kinda breaks because of that, however that does not appear to be relevant here.



SWEP.Author					= "Disseminate"
SWEP.Contact				= ""
SWEP.Purpose				= "To end your life."
SWEP.Instructions			= "Left click to take your own life."
SWEP.Category				= "Cube"

SWEP.Base					= "weapon_base"
SWEP.HoldType				= "pistol"

SWEP.Spawnable				= false
SWEP.AdminSpawnable			= true

SWEP.ViewModel				= "models/weapons/v_357.mdl"
SWEP.WorldModel				= "models/weapons/w_357.mdl"

SWEP.Primary.ClipSize		= 1
SWEP.Primary.DefaultClip	= 1
SWEP.Primary.Automatic		= false
SWEP.Primary.Ammo			= "pistol"

SWEP.Secondary.ClipSize		= -1
SWEP.Secondary.DefaultClip	= -1
SWEP.Secondary.Automatic	= false
SWEP.Secondary.Ammo			= "none"

SWEP.ShootSound 			= Sound( "Weapon_357.Single" );
SWEP.IronSightsPos 			= Vector( -2.9547, -28.7916, 0.9214 );
SWEP.IronSightsAng 			= Vector( 95.4548, -9.2427, 0 );

function SWEP:Initialize()
	
	self:SetWeaponHoldType( self.HoldType )
	self.Ironsights = false;
	
end

function SWEP:Think()
end

function SWEP:PrimaryAttack()
	
	self.Ironsights = true;
	
	if( SERVER ) then
		
		timer.Simple( 1, self.Shoot, self );
		
	end
	
end

function SWEP:SecondaryAttack()
end

function SWEP:GetViewModelPosition( pos, ang )
	
	local IRONSIGHT_TIME = 0.5;
	
	local bIron = self.Ironsights;
	
	if( bIron != self.bLastIron ) then
		
		self.bLastIron = bIron;
		self.fIronTime = CurTime();
		
	end
	
	local fIronTime = self.fIronTime or 0;

	if( !bIron && fIronTime < CurTime() - IRONSIGHT_TIME ) then
		
		return pos, ang;
		
	end
	
	local Mul = 1.0;
	
	if ( fIronTime > CurTime() - IRONSIGHT_TIME ) then
	
		Mul = math.Clamp( ( CurTime() - fIronTime ) / IRONSIGHT_TIME, 0, 1 );
		
		if( !bIron ) then
			
			Mul = 1 - Mul;
			
		end
	
	end

	local Offset = self.IronSightsPos;
	
	if( self.IronSightsAng ) then
	
		ang = ang * 1;
		ang:RotateAroundAxis( ang:Right(), 		self.IronSightsAng.x * Mul );
		ang:RotateAroundAxis( ang:Up(), 		self.IronSightsAng.y * Mul );
		ang:RotateAroundAxis( ang:Forward(), 	self.IronSightsAng.z * Mul );
		
	end
	
	local Right 	= ang:Right();
	local Up 		= ang:Up();
	local Forward 	= ang:Forward();
	
	pos = pos + Offset.x * Right * Mul;
	pos = pos + Offset.y * Forward * Mul;
	pos = pos + Offset.z * Up * Mul;

	return pos, ang;
	
end

function SWEP:Think()
	
	local pos = self.Owner:GetPos();
	
	sound.Play( self.ShootSound, self:GetPos() ); -- So the sound doesn't cut after I die
	
	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK );
	
	self.Owner:TakeDamage( 200, self, self );
	
end


make sure you’re running TakeDamage serverside-only

Ahh, very much appreciated. I’ll look into PrimaryAttack. I did google SWEP:Shoot() and fuck all came up, so I looked on the Wiki for an appropriate function to replace it with.

Give this a go.

[lua]
SWEP.Author = “Disseminate”
SWEP.Contact = “”
SWEP.Purpose = “To end your life.”
SWEP.Instructions = “Left click to take your own life.”
SWEP.Category = “Cube”

SWEP.Base = “weapon_base”
SWEP.HoldType = “pistol”

SWEP.Spawnable = false
SWEP.AdminSpawnable = true

SWEP.ViewModel = “models/weapons/v_357.mdl”
SWEP.WorldModel = “models/weapons/w_357.mdl”

SWEP.Primary.ClipSize = 1
SWEP.Primary.DefaultClip = 1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = “pistol”

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = “none”

SWEP.ShootSound = Sound( “Weapon_357.Single” );
SWEP.IronSightsPos = Vector( -2.9547, -28.7916, 0.9214 );
SWEP.IronSightsAng = Vector( 95.4548, -9.2427, 0 );

function SWEP:Initialize()

self:SetWeaponHoldType( self.HoldType )
self.Ironsights = false;

end

function SWEP:Think()

end

function SWEP:PrimaryAttack()

self.Ironsights = true;

if( SERVER ) then
	
	timer.Simple( 1, function()

			if !self.Owner then return end
			
			local pos = self.Owner:GetPos()

			sound.Play( self.ShootSound, self:GetPos() ) -- So the sound doesn't cut after I die

			self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )

			self.Owner:TakeDamage( 200, self, self )

	end)
	
end

end

function SWEP:SecondaryAttack()
end

function SWEP:GetViewModelPosition( pos, ang )

local IRONSIGHT_TIME = 0.5;

local bIron = self.Ironsights;

if( bIron != self.bLastIron ) then
	
	self.bLastIron = bIron;
	self.fIronTime = CurTime();
	
end

local fIronTime = self.fIronTime or 0;

if( !bIron && fIronTime &lt; CurTime() - IRONSIGHT_TIME ) then
	
	return pos, ang;
	
end

local Mul = 1.0;

if ( fIronTime &gt; CurTime() - IRONSIGHT_TIME ) then

	Mul = math.Clamp( ( CurTime() - fIronTime ) / IRONSIGHT_TIME, 0, 1 );
	
	if( !bIron ) then
		
		Mul = 1 - Mul;
		
	end

end

local Offset = self.IronSightsPos;

if( self.IronSightsAng ) then

	ang = ang * 1;
	ang:RotateAroundAxis( ang:Right(), 		self.IronSightsAng.x * Mul );
	ang:RotateAroundAxis( ang:Up(), 		self.IronSightsAng.y * Mul );
	ang:RotateAroundAxis( ang:Forward(), 	self.IronSightsAng.z * Mul );
	
end

local Right 	= ang:Right();
local Up 		= ang:Up();
local Forward 	= ang:Forward();

pos = pos + Offset.x * Right * Mul;
pos = pos + Offset.y * Forward * Mul;
pos = pos + Offset.z * Up * Mul;

return pos, ang;

end
[/lua]

EDIT: Ah damn ninjas

Thank you very, very much guys! It all works great now. I’ll quickly do some more research on the Think function, though, since I seem to have misinterpreted what it does.