Is there a better way to code the following?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I need an effective way to check every single second to be sure the player does not abuse a current bug in my gun script.

  1. What is the issue? Include screenshots / videos if possible!

The current issue is that if the player were to spam reload and shoot at the same time, the fire rate will double as a result if manage to time the spam correctly.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

The solution is that I created a loop to check every 0.05 seconds to see if the player has stopped firing to prevent the double fire rate bug. However, this still occurs as the player can still spam between the 0 - 0.05 seconds interval and activate the bug.

Here is my current code below:

mouse.Button1Down:Connect(function()
		IS_FIRING = true
		if debounce or (RELOADING_STATUS and CURRENT_BULLET == 0) or humanoid.Health < 0 then
			return
		end
		debounce = true
		while IS_FIRING do
			if CURRENT_BULLET == 0 then
				reload() -- can also be triggered when pressing R
			elseif humanoid.Health > 0 then
                -- shoot bullet
            end
-- The code below is what I want to improve. It basically another way of saying wait for "SHOT_INTERVAL" before shooting another bullet
			for i = 1, 20 * SHOT_INTERVAL do
				wait(0.05)
				if IS_FIRING == false then
					debounce = false
					return
				end
			end
-- need improvise code above
		end
		debounce = false
	end)

Is there a way where I can check every single second while the code waits for the next bullet to shoot?

Why not just:

wait(SHOT_INTVERVAL)
debounce = false
IS_FIRING = false

at the end of the Button1Down function.

This code is meant for an automatic weapon, meaning IS_FIRING is enabled until the player stops holding LMB, setting IS_FIRING to false

Oh, then try this. I have made one for my game

script.Parent.Activated:Connect(function() --This code will activated when player hold their left button
    if IS_FIRING == false and debouce == true then --i don't really know what debounce here used for but still try for it.
    IS_FIRING = true
         repeat
         --the bullet script here
      until IS_FIRING == false
      end
end)
script.Parent.Deactivated:Connect(function() --This will change the boolean into what you wanted when player stop hold the left button
if IS_FIRING == true and debouce == true then
IS_FIRING = false
--Your script here for animation, etc... 
      end
end)

I forgor to put “End” at the end of the script :skull:

I tried your code, but it double the chance of activating the bug :frowning:. Thanks for trying though :+1:

You can check out my script for advice, I just woke up :sleepy:

script.Parent.Activated:Connect(function()
	if isAuto == true and Ammo.Value > 0 and active == false and isSemi == false then
		
		FireAnim:Play()
		active = true
		fireso:Play()
		repeat
			wait(0.002)
			Ammo.Value = Ammo.Value - 1
							local unbullet = game.ReplicatedStorage.Folders.Parts.UnBullet:Clone()
				unbullet.Parent = workspace
			unbullet.CFrame = CFrame.new(script.Parent.BulletStartHere.Position)
			debris:AddItem(unbullet,6)
			local bullet = game.ReplicatedStorage.Folders.Parts.Bullet:Clone()
			bullet.Parent = workspace
			local speed = 700
			local antiGravity = 0.9
			local bf = Instance.new("BodyForce")
			bf.Force = Vector3.new(0, workspace.Gravity * bullet:GetMass() * antiGravity, 0)
			bf.Parent = bullet
			bullet.CFrame = CFrame.new(script.Parent["AK-47 EffectsPart"].Position, mouse.Hit.Position) * CFrame.Angles(math.random(-0.4,0.7),math.random(-0.4,0.7),math.random(-0.4,0.7))
			debris:AddItem(bullet, 1)
			bullet.Velocity = bullet.CFrame.LookVector * speed
			bullet.Touched:Connect(function(shot)
				if shot.Parent ~= char or shot.Parent.Parent ~= char then
				end
				local humanoid = shot.Parent:FindFirstChild("Humanoid")
				local RightArm = shot.Parent:FindFirstChild("Right Arm")
				local LeftArm = shot.Parent:FindFirstChild("Left Arm")
				local RightLeg = shot.Parent:FindFirstChild("RightLeg")
				local LeftLeg = shot.Parent:FindFirstChild("Left Leg")
				local head = shot.Parent:FindFirstChild("Head")
				local torso = shot.Parent:FindFirstChild("Torso")
				if RightArm or LeftArm then
					humanoid:TakeDamage(5)
					bullet:Destroy()
					local bullethit = game.ReplicatedStorage.Folders.Sounds["BulletHit(2)"]
					print("Right Arm , Left arm Is hit")
					bullethit:Play()
					if LeftLeg or RightLeg then
						humanoid:TakeDamage(5)
						bullet:Destroy()
						local bullethit = game.ReplicatedStorage.Folders.Sounds["BulletHit(2)"]
						print("Left leg , Right leg Is hit")
						bullethit:Play()
						if head then
							humanoid:TakeDamage(20)
							bullet:Destroy()
							local bullethit = game.ReplicatedStorage.Folders.Sounds["BulletHit(2)"]
							print("Head Is hit")
							bullethit:Play()
							if torso then
								humanoid:TakeDamage(10)
								bullet:Destroy()
								local bullethit = game.ReplicatedStorage.Folders.Sounds["BulletHit(2)"]
								print("Torso Is hit")
								bullethit:Play()
							end
						end
					end
				elseif not humanoid then
					if shot.Parent == script.Parent["Afk-47 MainPart"] or script.Parent == script.Parent["AK-47 EffectsPart"] or script.Parent.Parent == script.Parent["Afk-47 MainPart"] or script.Parent.Parent == script.Parent["AK-47 EffectsPart"] then
						end
					local choose = math.random(1,4)
					if choose == 1 then
						local sound1 = game.ReplicatedStorage.Folders.Sounds["Bullet Hit Concrete-4"]:Play()
					elseif choose == 2 then
						local sound2 = game.ReplicatedStorage.Folders.Sounds["Bullet Hit Concrete-2"]:Play()
					elseif choose == 3 then
						local sound3 = game.ReplicatedStorage.Folders.Sounds["Bullet Hit Concrete-1"]:Play()
					elseif choose == 4 then
						local sound4 = game.ReplicatedStorage.Folders.Sounds["Bullet Hit Concrete-5"]:Play()
						if bullet.Parent.Parent ~= nil and bullet.Parent ~= nil then
						end	
					end
				end
			end)
			if Ammo.Value <= 0 then
				fireso:Stop()
				active = false
				FireAnim:Stop()
				effect1.Enabled = false
				effect2.Enabled = false
				effect3.Enabled = false
				return
			end
			effect1.Enabled = true
			effect2.Enabled = true
			effect3.Enabled = true
			wait(0.002)
			effect1.Enabled = false
			effect2.Enabled = false
			effect3.Enabled = false
		until active == false

	elseif isAuto == false or Ammo.Value <= 0 then
		fireso:Stop()
		FireAnim:Stop()
		effect1.Enabled = false
		effect2.Enabled = false
		effect3.Enabled = false
		active = false


		local noammo = game.ReplicatedStorage.Folders.Sounds.NoAmmo
		noammo:Play()
	end
end)

script.Parent.Deactivated:Connect(function()
	if isAuto == true and Ammo.Value > 0 and active == true then
		FireAnim:Stop()
		fireso:Stop()
		active = false
	if reload == true then
		return
	elseif isAuto == false then
		return
	elseif Ammo.Value <= 0 then
			return
		end
	end
end)

Don’t allow the player to reload while shooting

2 Likes

I was planning to do that as a last resort if that’s the case. I want to make it convenient for the player to allow them to interrupt their reload if they still have ammo if you know what I mean.

does the bug only happen if they spam reload while shooting? If so add a debounce on the reload

Yes, that would be the bug. By the way, I noticed that the reason why that bug happens is that the while loop that I implemented was still running when I hit reload due to the BULLET_INTERVAL. Will your suggestion help the player exit the while loop if I try adding your suggestion? If not, do you know a way how I can exit that while loop when I hit reload? That could be the problem I am facing instead of the initial problem I posted.

How I would do it is when you reload, a variable = true.

in your loop, have an ifstatement checking when the variable == true

When it is true, you break

I tried to code it out and the bug is definitely much hard to activate, but it hasn’t been cleared completely. I will go ahead and take your temporary solution where the player can’t interrupt the reload for now and eventually will find a solution in the future. Thanks for helping out :+1:

1 Like