
AddCSLuaFile()

SWEP.PrintName = "Claws"
SWEP.Slot = 0
SWEP.SlotPos = 4

SWEP.Spawnable = true

SWEP.ViewModel = Model( "models/weapons/c_zombieswep.mdl" )
SWEP.WorldModel = ""
SWEP.ViewModelFOV = 90
SWEP.UseHands = true

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

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

SWEP.DrawAmmo = false

SWEP.HitDistance = 48

local SwingSound = Sound( "npc/fast_zombie/claw_miss1.wav" )
local HitSound = Sound( "npc/fast_zombie/claw_strike1.wav" )

function SWEP:Initialize()

	self:SetHoldType( "fist" )

end

function SWEP:SetupDataTables()

	self:NetworkVar( "Float", 0, "NextMeleeAttack" )
	self:NetworkVar( "Float", 1, "NextIdle" )
	self:NetworkVar( "Int", 2, "Combo" )

end

function SWEP:UpdateNextIdle()

	local vm = self:GetOwner():GetViewModel()
	self:SetNextIdle( CurTime() + vm:SequenceDuration() / vm:GetPlaybackRate() )

end

function SWEP:PrimaryAttack( right )
	local anim = "anim_fire"..math.random(1,4)
	local owner = self:GetOwner()

	local vm = owner:GetViewModel()
	vm:SendViewModelMatchingSequence( vm:LookupSequence( anim ) )

	self:EmitSound(SwingSound, 60, math.random(110,130), 0.5)

	self:UpdateNextIdle()
	self:SetNextMeleeAttack( CurTime() + 0.4 )

	self:SetNextPrimaryFire( CurTime() + 1 )

	if SERVER then
		if owner:Crouching() then
			owner:PlayFastGesture(ACT_SPECIAL_ATTACK2, true)
		else
			owner:PlayFastGesture(ACT_GESTURE_MELEE_ATTACK1, true)
		end
		owner:PlayVoiceLine("zombie_attack", 50)
	end
end

function SWEP:SecondaryAttack()

	if CLIENT then return end

	local ent = self:GetOwner()
	if ent.ZombieClass == "Spitter" then
		self:SetNextSecondaryFire(CurTime()+8)
		ent:SetSVAnimation("range_spit", true, true, true)
		timer.Simple(0.2, function()
			if !IsValid(ent) or !ent:Alive() then return end
			
			local pr = ents.Create("obj_vj_lnr_spit")
			pr:SetPos(ent:EyePos()+ent:GetForward()*32)
			pr:Spawn()
			pr:GetPhysicsObject():SetVelocity(ent:GetAimVector()*1000+Vector(0,0,100))
			timer.Simple(0.4, function()
				if !IsValid(ent) or !ent:Alive() then return end
				
				local pr = ents.Create("obj_vj_lnr_spit")
				pr:SetPos(ent:EyePos()+ent:GetForward()*32)
				pr:Spawn()
				pr:GetPhysicsObject():SetVelocity(ent:GetAimVector()*1000+Vector(0,0,100))
				timer.Simple(0.6, function()
					if !IsValid(ent) or !ent:Alive() then return end
					
					local pr = ents.Create("obj_vj_lnr_spit")
					pr:SetPos(ent:EyePos()+ent:GetForward()*32)
					pr:Spawn()
					pr:GetPhysicsObject():SetVelocity(ent:GetAimVector()*1000+Vector(0,0,100))
				end)
			end)
		end)
	elseif ent.ZombieClass == "Hazmat" then
		self:SetNextSecondaryFire(CurTime()+999)
		local anim = "nz_napalm_explode_"..math.random(1,3)
		local _, time = ent:LookupSequence(anim)
		ent:SetSVAnimation(anim, true, true, true)
		ent:EmitSound("vj_lnrspecials/explosivegasleak.wav", 80)
		timer.Simple(time, function()
			if !IsValid(ent) or !ent:Alive() or !IsValid(self) then return end
			ParticleEffect("vj_explosion2",ent:GetPos() + ent:GetUp()*48 + ent:GetForward()*1,Angle(0,0,0),nil) 
			ParticleEffect("vj_explosion1",ent:GetPos() + ent:GetUp()*15,Angle(0,0,0),nil)
			ParticleEffect("vj_explosionfire2",ent:GetPos() + ent:GetUp()*20,Angle(0,0,0),nil)
			ParticleEffect("vj_explosionfire1",ent:GetPos() + ent:GetUp()*20,Angle(0,0,0),nil) 	 
			util.ScreenShake(ent:GetPos(),100,200,1,2500)
			util.VJ_SphereDamage(ent,ent,ent:GetPos(),250,75,DMG_BLAST,false,true,{Force=100})
			ent:EmitSound("ambient/explosions/explode_"..math.random(1,9)..".wav", 90)	
			ent:Kill()
		end)
	elseif ent.ZombieClass == "Evo" then
		self:SetNextSecondaryFire(CurTime()+6)
		ent:SetSVAnimation("jump_attack", true, true, true)
		ent:SetVelocity(ent:GetAimVector()*200+Vector(0,0,600))
	elseif ent.ZombieClass == "Bomber" then
		self:SetNextSecondaryFire(CurTime()+10)
		ent:SetSVAnimation("range_throw", true, true, true)
		timer.Simple(0.6, function()
			if !IsValid(ent) or !ent:Alive() then return end
			
			local pr = ents.Create("obj_vj_grenade")
			pr:SetPos(ent:EyePos()+ent:GetForward()*32)
			pr:Spawn()
			pr:GetPhysicsObject():SetVelocity(ent:GetAimVector()*800+Vector(0,0,100))
			ent:EmitSound("vj_lnrspecials/bomber/zombine_readygrenade"..math.random(1,2)..".wav", 60)
		end)
	else
		self:SetNextSecondaryFire(CurTime()+10)
		ent:PlayVoiceLine("zombie_idle")
		ent:SetSVAnimation("nz_taunt_"..math.random(1,9), true, true, true)
		ent:SetHealth(math.min(ent:GetMaxHealth(), ent:Health()+25))
	end

end

local phys_pushscale = GetConVar( "phys_pushscale" )

function SWEP:DealDamage()

	local owner = self:GetOwner()

	local anim = self:GetSequenceName(owner:GetViewModel():GetSequence())

	owner:LagCompensation( true )

	local tr = util.TraceLine( {
		start = owner:GetShootPos(),
		endpos = owner:GetShootPos() + owner:GetAimVector() * self.HitDistance,
		filter = owner,
		mask = MASK_SHOT_HULL
	} )

	if ( !IsValid( tr.Entity ) ) then
		tr = util.TraceHull( {
			start = owner:GetShootPos(),
			endpos = owner:GetShootPos() + owner:GetAimVector() * self.HitDistance,
			filter = owner,
			mins = Vector( -10, -10, -8 ),
			maxs = Vector( 10, 10, 8 ),
			mask = MASK_SHOT_HULL
		} )
	end

	-- We need the second part for single player because SWEP:Think is ran shared in SP
	if ( tr.Hit && !( game.SinglePlayer() && CLIENT ) ) then
		self:EmitSound( HitSound )
	end

	local hit = false
	local scale = phys_pushscale:GetFloat()

	if ( SERVER && IsValid( tr.Entity ) && ( tr.Entity:IsNPC() || tr.Entity:IsPlayer() || tr.Entity:Health() > 0 ) ) then
		local dmginfo = DamageInfo()

		local attacker = owner
		if ( !IsValid( attacker ) ) then attacker = self end
		dmginfo:SetAttacker( attacker )

		dmginfo:SetInflictor( self )
		dmginfo:SetDamage( math.random( 10, 20 ) )

		if ( anim == "fists_left" ) then
			dmginfo:SetDamageForce( owner:GetRight() * 4912 * scale + owner:GetForward() * 9998 * scale ) -- Yes we need those specific numbers
		elseif ( anim == "fists_right" ) then
			dmginfo:SetDamageForce( owner:GetRight() * -4912 * scale + owner:GetForward() * 9989 * scale )
		elseif ( anim == "fists_uppercut" ) then
			dmginfo:SetDamageForce( owner:GetUp() * 5158 * scale + owner:GetForward() * 10012 * scale )
			dmginfo:SetDamage( math.random( 12, 24 ) )
		end

		SuppressHostEvents( NULL ) -- Let the breakable gibs spawn in multiplayer on client
		tr.Entity:TakeDamageInfo( dmginfo )
		SuppressHostEvents( owner )

		hit = true

	end

	if ( IsValid( tr.Entity ) ) then
		local phys = tr.Entity:GetPhysicsObject()
		if ( IsValid( phys ) ) then
			phys:ApplyForceOffset( owner:GetAimVector() * 80 * phys:GetMass() * scale, tr.HitPos )
		end
	end

	if ( SERVER ) then
		if ( hit && anim != "fists_uppercut" ) then
			self:SetCombo( self:GetCombo() + 1 )
		else
			self:SetCombo( 0 )
		end
	end

	owner:LagCompensation( false )

end

function SWEP:OnDrop()

	self:Remove() -- You can't drop fists

end

function SWEP:Deploy()

	local speed = GetConVarNumber( "sv_defaultdeployspeed" )

	local vm = self:GetOwner():GetViewModel()
	vm:SendViewModelMatchingSequence( vm:LookupSequence( "fists_draw" ) )
	vm:SetPlaybackRate( speed )

	self:SetNextPrimaryFire( CurTime() + vm:SequenceDuration() / speed )
	self:SetNextSecondaryFire( CurTime() + vm:SequenceDuration() / speed )
	self:UpdateNextIdle()

	if ( SERVER ) then
		self:SetCombo( 0 )
	end

	return true

end

function SWEP:Holster()

	self:SetNextMeleeAttack( 0 )

	return true

end

function SWEP:Think()

	local vm = self:GetOwner():GetViewModel()
	local curtime = CurTime()
	local idletime = self:GetNextIdle()

	if ( idletime > 0 && CurTime() > idletime ) then

		vm:SendViewModelMatchingSequence( vm:LookupSequence( "fists_idle_0" .. math.random( 1, 2 ) ) )

		self:UpdateNextIdle()

	end

	local meleetime = self:GetNextMeleeAttack()

	if ( meleetime > 0 && CurTime() > meleetime ) then

		self:DealDamage()

		self:SetNextMeleeAttack( 0 )

	end

	if ( SERVER && CurTime() > self:GetNextPrimaryFire() + 0.1 ) then

		self:SetCombo( 0 )

	end

end
