--this is a function to get player character rig
local function DetectRigAsync(Char)
	local Hum = Char:FindFirstChildOfClass("Humanoid")

	if Hum then
		if Hum.RigType == Enum.HumanoidRigType.R15 then
			return "R15"
		elseif Hum.RigType == Enum.HumanoidRigType.R6 then
			return "R6"
		end
	end
end

function RayCast(startPos, vec, rayLength)
	local Origin = startPos

	local Direction = vec * rayLength

	local Params = RaycastParams.new()
	Params.FilterType = Enum.RaycastFilterType.Blacklist
	Params.IgnoreWater = true
	Params.FilterDescendantsInstances = {Tool.Parent, workspace.BulletsFolder, Tool}

	local raycastResult = workspace:Raycast(Origin, Direction, Params)

	if raycastResult then
		return raycastResult.Instance, raycastResult.Position
	end
end

local function Reload()
	if not Reloading then
		Reloading = true

		if AmmoInClip ~= ClipSize and SpareAmmo > 0 then
			if RecoilTrack then
				RecoilTrack:Stop()
			end
			if WeaponGui and WeaponGui:FindFirstChild('Crosshair') then
				if WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
					WeaponGui.Crosshair.ReloadingLabel.Visible = true
				end
			end
			if ReloadTrack then
				ReloadTrack:Play()
			end
			script.Parent.Handle.Reload:Play()
			task.wait(ReloadTime)
			-- Only use as much ammo as you have
			local ammoToUse = math.min(ClipSize - AmmoInClip, SpareAmmo)
			AmmoInClip = AmmoInClip + ammoToUse
			SpareAmmo = SpareAmmo - ammoToUse
			UpdateAmmo(AmmoInClip)
			--WeaponGui.Reload.Visible = false
			if ReloadTrack then
				ReloadTrack:Stop()
			end
		end
		Reloading = false
	end
end

function OnFire()
	if IsShooting then return end
	if MyHumanoid and MyHumanoid.Health > 0 then
		if RecoilTrack and AmmoInClip > 0 then
			RecoilTrack:Play()
		end
		IsShooting = true
		while LeftButtonDown and AmmoInClip > 0 and not Reloading do
			if Spread and not DecreasedAimLastShot then
				Spread = math.min(MaxSpread, Spread + AimInaccuracyStepAmount)
				UpdateCrosshair(Spread)
			end
			DecreasedAimLastShot = not DecreasedAimLastShot
			if Handle:FindFirstChild('FireSound') then
				Pitch.Pitch = .8 + (math.random() * .5)
				Handle.FireSound:Play()
				Handle.Flash.Enabled = true
				flare.MuzzleFlash.Enabled = true
				--Handle.Smoke.Enabled=true --This is optional
			end
			if MyMouse then
				local targetPoint = MyMouse.Hit.Position
				local shootDirection = (targetPoint - Handle.Position).unit

				shootDirection = CFrame.Angles((0.5 - math.random()) * 2 * Spread,
					(0.5 - math.random()) * 2 * Spread,
					(0.5 - math.random()) * 2 * Spread) * shootDirection
				local hitObject, bulletPos = RayCast(Handle.Position, shootDirection, Range)
				local bullet

				if hitObject then
					bulletRE:FireServer(bulletPos)
					WeaponGui.Crosshair.Hit:Play()
				end
				if hitObject and hitObject.Parent then
					local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid")
					if hitHumanoid then
						local hitPlayer = game.Players:GetPlayerFromCharacter(hitHumanoid.Parent)
						if MyPlayer.Neutral or (hitPlayer and hitPlayer.TeamColor ~= MyPlayer.TeamColor) then
							ShootRE:FireServer(hitHumanoid, Damage)
							if bullet then
								bullet:Destroy()
								bullet = nil
								--bullet.Transparency = 1
							end
							task.spawn(UpdateTargetHit)
						end
					end
				end
				AmmoInClip = AmmoInClip - 1
				UpdateAmmo(AmmoInClip)
			end
			task.wait(FireRate)
		end
		Handle.Flash.Enabled = false
		IsShooting = false
		flare.MuzzleFlash.Enabled = false
		--Handle.Smoke.Enabled=false --This is optional
		if AmmoInClip == 0 then
			Handle.Tick:Play()
			--WeaponGui.Reload.Visible = true
			Reload()
		end
		if RecoilTrack then
			RecoilTrack:Stop()
		end
	end
end

local TargetHits = 0
function UpdateTargetHit()
	TargetHits = TargetHits + 1
	if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = true
	end
	task.wait(0.5)
	TargetHits = TargetHits - 1
	if TargetHits == 0 and WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = false
	end
end

function UpdateCrosshair(value, mouse)
	if WeaponGui then
		local absoluteY = 650
		WeaponGui.Crosshair:TweenSize(
			UDim2.new(0, value * absoluteY * 2 + 23, 0, value * absoluteY * 2 + 23),
			Enum.EasingDirection.Out,
			Enum.EasingStyle.Linear,
			0.33)
	end
end

function UpdateAmmo(value)
	if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('ClipAmmo') then
		WeaponGui.AmmoHud.ClipAmmo.Text = AmmoInClip
		if value > 0 and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
			WeaponGui.Crosshair.ReloadingLabel.Visible = false
		end
	end
	if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('TotalAmmo') then
		WeaponGui.AmmoHud.TotalAmmo.Text = SpareAmmo
	end
end


function OnMouseDown()
	LeftButtonDown = true
	OnFire()
end

function OnMouseUp()
	LeftButtonDown = false
end

function OnKeyDown(key)
	if string.lower(key) == 'r' then
		Reload()
		if RecoilTrack then
			RecoilTrack:Stop()
		end
	end
end

local TransparencyConnections = {}


function OnEquipped(mouse)

	Handle.EquipSound:Play()
	Handle.EquipSound2:Play()
	Handle.UnequipSound:Stop()
	RecoilAnim = WaitForChild(Tool, 'Recoil')
	ReloadAnim = WaitForChild(Tool, 'Reload')
	FireSound  = WaitForChild(Handle, 'FireSound')

	MyCharacter = Tool.Parent

	MyPlayer = game:GetService('Players'):GetPlayerFromCharacter(MyCharacter)
	MyHumanoid = MyCharacter:FindFirstChild('Humanoid')
	MyTorso = MyCharacter:FindFirstChild('Torso')
	MyMouse = mouse
	WeaponGui = WaitForChild(Tool, 'WeaponHud'):Clone()

	if FPSHandsEnbled then
		if AutoFirstPerson then
			MyPlayer.CameraMode = Enum.CameraMode.LockFirstPerson
		end

		local Rig = DetectRigAsync(MyCharacter)

		if Rig == "R15" then
			local WhitelistedBodyParts = {"LeftHand", "LeftLowerArm", "LeftUpperArm", "RightHand", "RightLowerArm", "RightUpperArm"}

			for i, bodypart in pairs(MyCharacter:GetDescendants()) do
				if table.find(WhitelistedBodyParts, bodypart.Name) and bodypart:IsA("BasePart") then
					bodypart.LocalTransparencyModifier = bodypart.Transparency

					TransparencyConnections[bodypart.Name] = bodypart:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
						bodypart.LocalTransparencyModifier = bodypart.Transparency
					end)
				end
			end
		elseif Rig == "R6" then
			local WhitelistedBodyParts = {"Right Arm", "Left Arm"}
			
			for i, bodypart in pairs(MyCharacter:GetDescendants()) do
				if table.find(WhitelistedBodyParts, bodypart.Name) and bodypart:IsA("BasePart") then
					bodypart.LocalTransparencyModifier = bodypart.Transparency

					TransparencyConnections[bodypart.Name] = bodypart:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
						bodypart.LocalTransparencyModifier = bodypart.Transparency
					end)
				end
			end
			
		end
	end

	if WeaponGui and MyPlayer then
		WeaponGui.Parent = MyPlayer.PlayerGui
		UpdateAmmo(AmmoInClip)
	end
	if RecoilAnim then
		RecoilTrack = MyHumanoid:LoadAnimation(RecoilAnim)
	end

	if ReloadAnim then
		ReloadTrack = MyHumanoid:LoadAnimation(ReloadAnim)
	end

	if MyMouse then
		-- Disable mouse icon
		MyMouse.Icon = "http://www.roblox.com/asset/?id=18662154"
		MyMouse.Button1Down:connect(OnMouseDown)
		MyMouse.Button1Up:connect(OnMouseUp)
		MyMouse.KeyDown:connect(OnKeyDown)
	end
end