[Help] Trying to do an on / off codeblock in lua

Hey guys!

I’m currently working in my selfhelp thread in the forums and seem to be stuck! Precurser - I’m NOT a guru with regards to lua programming.

I’m trying to make an on off switch using commands. For example.
Native starts in off state. Then you do: /command on and the native activates. To be more specific I’m trying to create a marker at the entering of a command!

So far I have:

function ShowNotification( text )
        SetNotificationTextEntry("STRING")
        AddTextComponentSubstringPlayerName(text)
        DrawNotification(false, false)
end

RegisterCommand("borders", function(source, args, RawCommand)
        local flag = 0
        if args[1] == 'on' then flag = 'true' break
        else if args[1] == 'off' then flag = 'false' break
        else ShowNotification("~g~~b~Wrong usage! Try this: /borders [on/off]") break
        end
                end
end)

Citizen.CreateThread(function()
        while flag == 1 do
        Wait(0)

DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)

end
end)

But the command isn’t returning anything specific. what are some best practices that I’m missing. Are there any syntax errors that you lua greybeards can spot?

Please let me know! Thanks for your help!

When you set flag to 0, it terminates the thread/while loop. You can either check the flag inside a while true do loop or you can just put the thread you have now inside a function and call the function when flag == 1. Also you should probably keep flag set to a boolean or an int, you are changing it to a string but still checking if it is 1 in the loop.

But how will I be able to disable it if it’s on?

Also, I’m a little stuck on the idea of calling functions. I know wiht C, for example, you can just call it by name, and wrap the function contents in variables, but for LUA, how is it?

local flag = false

function ShowNotification( text )
	SetNotificationTextEntry("STRING")
	AddTextComponentSubstringPlayerName(text)
	DrawNotification(false, false)
end

RegisterCommand("borders", function(source, args, RawCommand)
	if args[1] == 'on' then
		 flag = true
	else if args[1] == 'off' then
		 flag = false
	else 
		ShowNotification("~g~~b~Wrong usage! Try this: /borders [on/off]")
	end
end)

Citizen.CreateThread(function()
	while true do
		sleep = 500
		while flag  do
			sleep = 0
			DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
		end
		Citizen.Wait(sleep)
	end
end)

Changed your code with my example… and has not been tested but should work… to optimize the code a fair bit.

Changes:

  • You set Flag as a local inside of a command so it would be nil out side of that command - I have set it as a local for the entire script and set it to false.

  • In the RegisterCommnad you were setting flag = ‘true’ which was setting it as a string and then in the loop below you were checking for 1/0 or boolean. I have set it as the correct value.

  • Your citizen.createthread would run one time and then stop sicne flag was not set. I have formated it to run the entire time, but only drawmarker while flag is true.

  • The sleep functionality is to allow the script to wait 1/2 a second before it checks to see if flag is true… but if flag is true is has a 0 tick wait so the marker doesn’t flash.

Hopefully you understand the points I have made and can learn from the example (and ofcourse hopefully the code works as i said i have not tested this personally).

SpikE

Hey Spike! Thanks for the contribution!
Unfortunately, this codeblock didn’t work, but let me first tell you what I’ve learned so far

What I’ve learned:
Citizen.CreateThread can contain other logics underneath such as ifs, while, or do statements!

Creating a local variable outside of a function will allow you to reference it in different functions

With that being said, when trying the command, it froze my client. After some trial and error, I figured out it was because of the sleep functions, so I replaced them with "Wait"s instead and it worked!

Although this worked, I know that while this works, something’s not right about it because it spams up the console in fiveM.

Anyways, the modified code is:

local flag = false

function ShowNotification( text )
	SetNotificationTextEntry("STRING")
	AddTextComponentSubstringPlayerName(text)
	DrawNotification(false, false)
end

RegisterCommand("borders", function(source, args, RawCommand)
        if args[1] == 'on' then
                 flag = true
        else if args[1] == 'off' then
                 flag = false
else 
		ShowNotification("~g~~b~Wrong usage! Try this: /borders [on/off]")
        end
end
end)

Citizen.CreateThread(function()
        while true do
                Wait(500)
                while flag == true do
                        Wait(0)
			DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
        end
        end
end)

In terms of syntaxes / best practices, is there anything you notice that’s not correct?
Please let me know!

Thanks for your help thus far! <3

1 Like

The Wait(500) and Wait(0) you have will make the marker flash since it will only draw every 1/2 sec instead of every tick. Try replacing

Citizen.CreateThread(function()
	while true do
		sleep = 500
		while flag  do
			sleep = 0
			DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
		end
		Citizen.Wait(sleep)
	end
end)

with

Citizen.CreateThread(function()
	while true do
		sleep = 500
		while flag  do
			sleep = 0
			DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
		end
		Wait(sleep)
	end
end)

and see if that works.

SpikE

As far as syntax the one major one i spot is

while flag == true do

in lua while checking a boolean you can use this syntax:

while flag do     <-- will only process if flag = true

while not flag do   <-- will only process if flag = false

Hey Spike;

Unfortunately, the code block you’ve provided still freezes my client; As mentioned, the removing the sleep blocks and replacing them with waits seems to stop the process from freezing, but it spams the console (f8). Have you been able to test the code on your client?

Your easiest solution would be

Citizen.CreateThread(function()
    while true do
        if flag do
            DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
        end
        Citizen.Wait(0)
    end
end)

For something more optimal, maybe try this

Citizen.CreateThread(function()
    while true do
        if flag do
            DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
            Citizen.Wait(0)
            break
        end
        Citizen.Wait(500)
    end
end)

The idea here being that if ‘flag’ returns true, it will draw the marker every tick and repeat the loop by calling break, but if it returns false then it will revert back to checking only every 500ms. Let me know if that works, I haven’t actually tested it either :stuck_out_tongue:

1 Like

Hey guys! I got it! Somehow i took the same code that i updloaded before (the second one, and I’m not sure how It worked this time around), but it works just nice!

Here’s the finished product:

local flag = false

function ShowNotification( text )
        SetNotificationTextEntry("STRING")
        AddTextComponentSubstringPlayerName(text)
        DrawNotification(false, false)
end

RegisterCommand("borders", function(source, args, RawCommand)
        if args[1] == 'on' then
                 flag = true
        else if args[1] == 'off' then
                 flag = false
else
                ShowNotification("~g~~b~Wrong usage! Try this: /borders [on/off]")
        end
end
end)

Citizen.CreateThread(function()
        while true do
                Wait(500)
                while flag == true do
                        Wait(0)
     			DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
                        end
                    end
end)

Thanks guys for your help as I got my act together! Cheers!

Citizen.CreateThread(function()
    while true do
        if flag do
            DrawMarker(43, -1064.04, 03156.26, 15.05, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1, 0, 0, 0, false, false, 2, false)
            Citizen.Wait(0)
        end
    end
end)

Your first example would freeze FiveM as soon as flag is not true since the wait is inside the if statement.

Your 2nd example of using break could work and is the same thing i suggested except i use sleep and have 1 wait - and just set the variable that Wait uses depending on the flags above it.

SpikE

1 Like

Of course, what was I thinking :joy: I’ll correct that.

1 Like