Irregular Ammo Deduction?

Basically for some reason when you spam click ammo gets deducted in threes or twos and wen you hold your mouse, it gets deducted really slowly.

local remaining = game.ReplicatedStorage.Remaining
local reloadrt = game.ReplicatedStorage.Reload
local tool = script.Parent
local mouse = game.Players.LocalPlayer:GetMouse()
local plr = game:GetService("Players").LocalPlayer
local tool = script.Parent
local playergui = plr.PlayerGui
local firerate = 0.4
local debouncereload = false
local uis = game:GetService("UserInputService")
local is_shooting = false
local debounce = false
local maxammo = 16
local amount = 0
local value = plr.Bulletpack.Bullet
local character = plr.Character or plr.CharacterAdded:Wait()
local ammo_out = false
local rt = game.ReplicatedStorage:FindFirstChild("Shoot")
local ammo = 16
tool.Equipped:Connect(function()
	screengui1 = game.ReplicatedStorage.AmmoGuiGlock:Clone()
	screengui1.Parent = playergui
	screengui1.Enabled = true
	text = screengui1.Frame.Ammo
	text.Text = tostring(ammo) .. "/" .. maxammo
	if value.Value <= ammo then
		text.Text = tostring(value.Value) .. "/" .. maxammo

	end
	 conn1 = mouse.Button1Up:Connect(function()
		print("os")
		if is_shooting == true then
			is_shooting = false
		end
		is_shooting = false
		print(is_shooting)
	end)
 conn2 =	mouse.Button1Down:Connect(function()
		if ammo == 0 then return end
		is_shooting = true
		print(is_shooting)
		while is_shooting == true do
			print(is_shooting)
			ammo -= 1
			rt:FireServer(mouse.Target, script.Parent, mouse.Hit.Position, mouse.TargetFilter)
			mouse.TargetFilter = script.Parent.Handle
			print("aaa")
			if ammo == 0 then
				text.Text = "Reloading"
				is_shooting = false
				task.wait()
				ammo = maxammo
				if ammo >= value.Value then
					text.Text = value .Value.. "/" .. maxammo
				end
				if value.Value > ammo then
					text.Text = ammo .. "/" .. maxammo
				end
			end
			if value.Value >= ammo then
				text.Text = ammo .. "/" .. maxammo
			end
			if ammo > value.Value then
				text.Text = value.Value .. "/" .. maxammo
			end
			if value.Value == 0 then
				text.Text = "Out of Ammo"
				return
			end		
			task.wait(firerate)
		end
	end)
end)
tool.Unequipped:Connect(function()
	is_shooting = false
	screengui1:Destroy()
	conn1:Disconnect()
	conn2:Disconnect()
end)
local damage = {}
local config
function damage.IdentifyGun(gunname, target, muzzleeffect, plr, gunshot, player)
	local debounce = false
	local character = player.Character or player.CharacterAdded:Wait()
config = script.Configuration
local folder = config:FindFirstChild(gunname)
local damagevar = folder.Damage
local ammovar = folder.Ammo
local counter = 0
local ammo = character:FindFirstChild(gunname .. " ammo")
if ammo == nil then return end

local fireratevar = folder.FireRate
local reloadtimevar = folder.ReloadTime
local maxammovar = folder.MaxAmmo
if target == nil then
	return
end
		if ammo.Value > 0 and debounce == false then
		warn(ammo.Value .. " IS THE AMMO VALUE")
warn(fireratevar.Value .. " IS THE FIRERARE VALUE!")
			ammo.Value -=1
		debounce = true
		muzzleeffect.Enabled = true
		gunshot:Play()
		task.wait(fireratevar.Value)
		debounce = false
		muzzleeffect.Enabled = false
		if target.Parent:FindFirstChild("Humanoid") then
			target.Parent.Humanoid:TakeDamage(damagevar.Value)
		end
			if ammo.Value == 0 then
				debounce = true
				task.wait(reloadtimevar.Value)
				ammo.Value = maxammovar.Value
				debounce = false
				return
			end
end
end
return damage

(The firerate is 0.1)

you put a while loop inside of a connection. Not a very good idea and might be the cause

It’s the only way I can make an automatic gun unfortunately, plus I highly doubt it’s the problem

Can anybody help me with this?