Like press e to pickup and drop something? Because the toggle looks right to me at the bottom.
Not really. What I want is this :
The player is near a place where he can recolt something.
The server pops this kind of message :
Then the player press the ‘E’ key
The server pops this message :
It also should pops a message in the bottom of the screen telling the player that he is recolting something but this message is really quick, it doesn’t stay at screen.
Then, the key to stop doing the action isn’t working it’s doing nothing.
OK so basically while they are doing something if they want to kinda cancel out the action they just press e again. I’m sorry just a bit confused.
Yes, that exactly the behavior i’m looking for.
What I would do is make a variable.
local isMoving = false
When they click e the first time check if they are close enough and if isMoving is false then start recolting if they are really close enough and isMoving = true then stop recolting then reset variable back to false.
I am sorry I am on my phone so examples are limited.
I’m already using a variable to know if the player isRecolting or not.
By default the variable is set to FALSE
When he first clicks on ‘E’ the variable is set to TRUE and if he press ‘E’ again it should return to FALSE
It’s shown in my code example.
Doesn’t seems to work that way sadly.
Maybe put the is control just pressed statement above everything. Sorry I am just thinking because that looks right to me. But out of all of us there is always something small we look over.
Maybe put the control in another thread. I believe your issue is you’re using Citizen.Wait
on your thread which, is stopping the code from executing the IsControlJustPressed(1, 38)
function.
Better Explanation:
function doRecolt()
if (isRecolting == false) then
DisplayHelpText("Appuyez sur ~INPUT_PICKUP~ pour récolter.")
else
Citizen.Wait(timeForRecolt - 800) -- Stops the thread for "timeForRecolt" miliseconds
TriggerEvent("player:receiveItem", tonumber(JOBS[jobId].recolt_item_id), 1) -- After "timeForRecolt" seconds, the thread can run again (this and other code can run)
end
if IsControlJustPressed(1, 38) then -- Has to wait until the thread is running again
isRecolting = not isRecolting
end
end
So, try something like this, along side your current code:
Citizen.CreateThread(function()
while true do
Citizen.Wait(0) -- Needed
if IsControlJustPressed(1, 38) then
isRecolting = not isRecolting
end
end
end)
With this code, isRecolting is never FALSE neither it’s TRUE. I think the two IsControlJustPressed are executed at the same time.
The solution should be very simple in theory, I can’t figure out why it’s so difficult to get the desired behavior.
I apologize if I was no help earlier I don’t have Internet at home so I can’t really use my pc to help. So I am stuck to my phone.
This could be the case. Are you printing the various variables to the console to see what values they are and when certain stuff is happening (e.g. when the button is pressed)? You should also remove the original IsControlJustPressed
as they can both fire at the same time and the isRecolting
will look like it’s not changing when in fact, it’s changing twice instantly.
Also, what is “timeForRecolt”? I see that you’re taking 800 away from it, why is that? I hope that you’re also aware that the Wait
function takes the number of milliseconds to wait (1 second = 1000 milliseconds).
Note: If you’ve still not figured this out in half an hour, I’ll see if I can cobble something together for you
I’m not printing the variables but I will do.
Nevertheless I’m pretty sure that the both are firing at the same time. When I try to ‘Press E’ in game nothing happen.
timeForRecolt is a variable, it’s role is to wait before the player receive an item from his recolting action. Otherwise he would receive an item at each tick.
This system is part of a recolt / treatment / sell system that I try to build.
That’s very nice of you to try to cobble something, i’m waiting for you. To wait, i’m going to print the variables and test other things.
Thank’s in advance
EDIT :
-- Listen for Player to be near something
Citizen.CreateThread(function()
while true do
Citizen.Wait(1)
if(IsNearSomething() == 're') then
doRecolt()
elseif(IsNearSomething() == 'tr') then
DisplayHelpText("Appuyez sur ~INPUT_PICKUP~ pour traiter.")
doTreatment()
elseif(IsNearSomething() == 'se') then
DisplayHelpText("Appuyez sur ~INPUT_PICKUP~ pour vendre.")
doSell()
else
isRecolting, isTreating, isSelling = false
end
end
end)
-- Actions de récolte
function doRecolt()
if IsControlJustPressed(1, 38) then -- If INPUT_PICKUP Is pressed (touche E)
isRecolting = not isRecolting
end
if (isRecolting == false) then
DisplayHelpText("Appuyez sur ~INPUT_PICKUP~ pour récolter.")
else
DisplayHelpText("Appuyez sur ~INPUT_PICKUP~ pour ~r~arrêter~w~ de récolter.")
drawTxt("~b~Récolte~w~ en cours...",10,0,0.4,0.95,0.4,255,255,255,255)
--Citizen.Wait(timeForRecolt - 800)
TriggerEvent("player:receiveItem", tonumber(JOBS[jobId].recolt_item_id), 1)
drawTxt("~g~+1~w~".. tostring(JOBS[jobId].recolt_item_libelle),10,0,0.4,0.95,0.4,255,255,255,255)
end
end
Ok, when I comment this line --Citizen.Wait(timeForRecolt - 800)
it’s working very well ! Exactly what I want.
Well, nearly, I receive 30 items / second when i’m recolting, how can I set a timer which wouldn’t mess up my script ?
So, the code below allows the player to “toggle” the action:
local isRecolting = false -- Is player recolting?
local recoltTime = 1000 -- 1 second
Citizen.CreateThread(function()
Citizen.Trace("Created control thread")
while true do
Citizen.Wait(1)
if IsControlJustPressed(1, 38) then -- When they press INPUT_PICKUP (default e)
isRecolting = not isRecolting -- Toggle the boolean
end
-- Show the different messages
if isRecolting then
-- Show the message telling them how to stop
else
-- Show the message telling them how to start
end
end
end)
-- Thread to give the player stuff when recolting
Citizen.CreateThread(function()
Citizen.Trace("Created main thread")
while true do
Citizen.Wait(1)
if isRecolting then
Citizen.Wait(recoltTime) -- Wait for recoltTime (1 second)
-- Since isRecolting could have changed since we started waiting. Double check it
if isRecolting then
-- TODO: Give the player stuff?
Citizen.Trace("Giving player something!")
end
end
end
end)
Obviously, you’ll need to change it to fit your specific use case but, the basics are there
Thank’s a lot, that works very well !
Still some details to fix but my mains problems are gone, really, thank’s a lot.
Or should we put this .?
Hey ! Thanks for your help, it works but I have an issue.
I’m using this to show the message :
function DisplayHelpText(str)
SetTextComponentFormat("STRING")
AddTextComponentString(str)
DisplayHelpTextFromStringLabel(0, 0, 1, -1)
end
if isRecolting then
-- Show the message telling them how to stop
DisplayHelpText("Appuyer sur ~INPUT_PICKUP~ pour ~r~arrêter~w~.")
else
-- Show the message telling them how to start
DisplayHelpText("Appuyer sur ~INPUT_PICKUP~ pour ~g~récolter~w~.")
end
The issue is that I have the “pop-up GTA sound” playing in a loop and that’s really annoying, do you know if I can mute it or show the message in the top left corner of the screen without this pop up sound ?
Thanks
I’ll leave this native here for you (in future, have a look at <game>/citizen/scripting/lua/natives.lua
for a better understanding of some natives ).
function DisplayHelpTextFromStringLabel(p0, loop, beep, shape)
return _in(0x238FFE5C7B0498A6, p0, loop, beep, shape)
end
#####Hint: Change your 1 into a 0
Thanks <3 I should’ve done that on my own sorry ^^
Hello, I want to do the same. but with one option I want to start a function that contains a loop cycle, and with another I want to stop that cycle. I can’t do it.
Mi codigo:
Client:
local stop = true
function DisplayHelpText(str)
SetTextComponentFormat("STRING")
AddTextComponentString(str)
DisplayHelpTextFromStringLabel(0, 0, 1, -1)
end
Citizen.CreateThread(function()
Citizen.Trace("Created control thread")
while true do
Citizen.Wait(1)
if IsControlJustPressed(1, 38) then -- When they press INPUT_PICKUP (default e)
isRecolting = not isRecolting -- Toggle the boolean
end
-- Show the different messages
if isRecolting then
DisplayHelpText("Presiona ~INPUT_PICKUP~ para ~r~Cancelar~w~.")
else
DisplayHelpText("Presiona ~INPUT_PICKUP~ para ~r~Farmear~w~.")
end
end
end)
-- Thread to give the player stuff when recolting
Citizen.CreateThread(function()
Citizen.Trace("Created main thread")
while true do
Citizen.Wait(1)
if isRecolting then
Citizen.Wait(recoltTime) -- Wait for recoltTime (1 second)
-- Since isRecolting could have changed since we started waiting. Double check it
if isRecolting then
-- TODO: Give the player stuff?
Citizen.Trace("Giving player something!")
ESX.ShowNotification("~r~Farmeando")
start_farm()
else
ESX.ShowNotification("~r~Dejo de farmear")
stop = false
end
end
end
end)
Server:
ESX.RegisterServerCallback('fishing:getCantidad', function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
local conteo = xPlayer.getInventoryItem('marijuana').count
cb(conteo)
end)
RegisterServerEvent("fishing:dropmari")
AddEventHandler("fishing:dropmari", function()
local _source = source
local xPlayer = ESX.GetPlayerFromId(_source)
xPlayer.addInventoryItem('marijuana', 1)
end)
Here the process starts, but when it is time to cancel nothing happens …
Citizen.CreateThread(function()
Citizen.Trace("Created main thread")
while true do
Citizen.Wait(1)
if isRecolting then
Citizen.Wait(recoltTime) -- Wait for recoltTime (1 second)
-- Since isRecolting could have changed since we started waiting. Double check it
if isRecolting then
-- TODO: Give the player stuff?
Citizen.Trace("Giving player something!")
while isRecolting do
Citizen.Wait(10000)
TriggerServerEvent("fishing:dropmari")
end
else
ESX.ShowNotification("~g~Cancelaste!") -- This never happens
end
end
end
end)