How do I stop the rest of this code from running?

So currently, I’m trying to make it so that if you unequip while reloading, all the values get reset and the function is canceled. How do I cancel the function from inside of it?

When the event is fired I want to reset using code, and then return out from the function and stop.

function Reload()
	if Enabled and not Reloading and (Ammo > 0 or not Module.LimitedAmmoEnabled) and Mag < Module.AmmoPerMag and not rollval.Value then
		ResetReload.Event:Connect(function()
			-- obviously I'd reset everything here
			
			return -- I want to return out and cancel the rest here if this event is fired
		end)
		
		Reloading = true
		reloadval.Value = true 
		if scopeval.Value then
			TweeningService:Create(Camera, TweenInfo.new(Module.TweenLengthNAD, Module.EasingStyleNAD, Module.EasingDirectionNAD), {FieldOfView = 70}):Play()
		end
		if AimDown then
			setcrossscale(1)
			if Module.AimAnimationsEnabled and AimIdleAnim and AimIdleAnim.IsPlaying then
				AimIdleAnim:Stop(.2)
				if IdleAnim then IdleAnim:Play(nil,nil,Module.IdleAnimationSpeed) end
			end
			--[[local GUI = game:GetService("Players").LocalPlayer.PlayerGui:FindFirstChild("ZoomGui")
			if GUI then GUI:Destroy() end]]
			Scoping = false
			game:GetService("Players").LocalPlayer.CameraMode = Enum.CameraMode.Classic
			UserInputService.MouseDeltaSensitivity = InitialSensitivity
			AimDown = false
		end
		UpdateGUI()
		if Module.ShotgunReload then
			for i = 1,(Module.AmmoPerMag - Mag) do
				if ShotgunClipinAnim then ShotgunClipinAnim:Play(nil,nil,Module.ShotgunClipinAnimationSpeed) end
				Handle.ShotgunClipin:Play()
				wait(Module.ShellClipinSpeed)
			end
		end
		if Module.TacticalReloadAnimationEnabled then
			if Mag > 0 then
				if TacticalReloadAnim then TacticalReloadAnim:Play(nil,nil,Module.TacticalReloadAnimationSpeed) end 
				Handle.TacticalReloadSound:Play()
			else
				if ReloadAnim then ReloadAnim:Play(nil,nil,Module.ReloadAnimationSpeed) end
				Handle.ReloadSound:Play()
			end
		else
			if ReloadAnim then 
				if not sprintval.Value then
					ReloadAnim:Play(nil,nil,Module.ReloadAnimationSpeed) 	
				else
					ReloadEasedAnim:Play(1, 1, TweenInfo.new(.4, Enum.EasingStyle.Quart, Enum.EasingDirection.Out))
					--ReloadAnim:Play(.33,nil,Module.ReloadAnimationSpeed) 
				end
				
			end
			Handle.ReloadSound:Play()
		end
		wait(Module.ReloadTime)
		if Module.LimitedAmmoEnabled then
			local ammoToUse = math.min(Module.AmmoPerMag - Mag, Ammo)
			Mag = Mag + ammoToUse
			Ammo = Ammo - ammoToUse
		else
	    	Mag = Module.AmmoPerMag
		end
		ChangeMagAndAmmo:FireServer(Mag,Ammo)
		reloadval.Value = false
		Reloading = false
		UpdateGUI()
	end
end
1 Like

The use of courotines might help you. Hint courotine.yeild

Try creating an if statement in your code that will check if the event has been fired and if not will run the rest of your code. This needs to use a wide scope variable.

	if Enabled and not Reloading and (Ammo > 0 or not Module.LimitedAmmoEnabled) and Mag < Module.AmmoPerMag and not rollval.Value then

        resetReload = false -- This is our wide scope variable

		ResetReload.Event:Connect(function()
			-- obviously I'd reset everything here
			
			resetReload = true -- Set the wide scope variable to true
		end)
		
        if resetReload then return end -- Stop here if ResetReload was called

        -- The rest of your reload code below
		Reloading = true
		reloadval.Value = true 

Edit: Make sure your resetReload variable isn’t the same name as your event variable

1 Like

This would only work if the event was fired before checking if the ResetReload value was true. After that it will fail to stop. Meaning that you would have to check whether the ResetReload value was true after every line of code or every important function

2 Likes

This is a good idea but I don’t think it would work, because the whole purpose of this is to stop it while it’s running.

This doesn’t make a difference because someone could reload while it’s false, and then I call the event and it wouldn’t do anything because it’s already running

Didn’t think of that, you could try making the reload script it’s own script and just disabling it/enabling it completely from a separate script while running your reload reset code in that separate script, only thing I could really think of

As I noted above, courotines might be useful here, as you could wrap the entire function inside a coroutine and then yeild that courotine when you need to. You wouldnt have to worry about this eating up memory usage as once you yeild a courotine memory usage doesnt grow.

2 Likes

This would be a cleaner and better approach to the method I proposed above, try using coroutines

So if I yielded it, how would I then cancel it out so that when I call it again it doesn’t start from when it was yielded?

When you yield the coroutine, in your case your essentially just abandoning that thread all together. Once you need to reload again, you just set that old coroutine variable to the new coroutine which you should set at the start of every reload. Hence this is very similar to disabling a script or destroying it.

1 Like

So wrap, yield, then create again, right?
The reload function is in the global scope so I’d have to set the variable to nil and then set it back to the coroutine

And you said they dont cause memory leaks, so I’m good right?

1 Like

No memory leaks, yeilding a coroutine stops further memory usage. Plus you even said you would reset the variable to nil anyways, so you’re good

1 Like

Alright. Thanks for your help!

One more question. Can I yield the coroutine from outside of the coroutine?