How to add a check which works even when Citizen.Wait is running

I am using some sort of progressBars which trigger with exports. I made a car wash and everything is fine but as I have something like:

  exports['progressBars']:startUI(25000, "We're washing your car")
  Citizen.Wait(25000)

I don’t know how to have the script to always check if player is moving away even when Citizen.Wait is running… I am using GetEntityCoords and so on and I have an export for stopping the progressBar but as the script is on pause for 25 seconds, it won’t stop the progressBar if I move away. I hope you understand
Thanks

Citizen.CreateThread(function()
    local timer = 0
    
    while timer < 25000 do
        Wait(100)
        timer = timer + 100
        -- here check what you need and if something is wrong then just return
    end
    
    -- here goes code if everything is ok
    
end)
1 Like

smth like that

exports['progressBars']:startUI(25000, "We're washing your car")
Citizen.CreateThread(function()
    local timer = 0

    while timer < 25000 do
        Wait(100)
        timer = timer + 100
        local dist = #(GetEntityCoords(entity) - yourPosToCheckDistance)
        if dist > yourRadiusYouAreChecking then
            return notificationFunction("You are too far from your car")
        end
    end

    -- here goes code if everything is ok
    exports['progressBars']:removeProgressBarFunctionName()
    notificationFunction("Your car is clean")
end)
2 Likes

Thank you @qq_strike
I didn’t use your method because I realized that I already had another function for showing and hiding the UI so I put the removeprogressbarfunction in the else statement and works great but now I have another problem and I hope that it’s the last one too xD

If I move away with the car, everything breaks and it won’t get repaired and progressBar will disappear as intended to but if I move the car, and return to the spot before the 25 seconds the car is cleaned.

-- Show NUI
local isDisplayable = true

Citizen.CreateThread(function()
 while true do
  Citizen.Wait(0)
   local ped = GetPlayerPed(-1)
  if GetDistanceBetweenCoords(-699.67, -933.01, 18.10, GetEntityCoords(ped)) < 5.0 and IsPedInAnyVehicle(ped, true) then
   if isDisplayable then
      TriggerEvent("nui:display", true)
   end
  else
   TriggerEvent("nui:display", false)
   isDisplayable = true
   exports['progressBars']:closeUI()
  end
 end
end)

-- Carwash
Citizen.CreateThread(function()
  while true do
    Citizen.Wait(0)
    local ped = GetPlayerPed(-1)
    local vehicle = GetVehiclePedIsIn(ped, false)
    if IsControlJustPressed(0, 18) and GetDistanceBetweenCoords(-699.67, -933.01, 18.10, GetEntityCoords(ped)) < 5.0 and IsPedSittingInAnyVehicle(ped) then
      isDisplayable = false
      TriggerEvent("nui:display", false)
      exports['progressBars']:startUI(25000, "We're washing your car.")
      Citizen.Wait(25000)
     if GetDistanceBetweenCoords(-699.67, -933.01, 18.10, GetEntityCoords(ped)) < 5.0 and IsPedSittingInAnyVehicle(ped) then
      SetVehicleDirtLevel(vehicle, 0.0)
      TriggerEvent('chat:addMessage', {
        args = {"We've washed your car."}
      })
     end
    end
    if IsControlJustPressed(0, 177) and GetDistanceBetweenCoords(-699.67, -933.01, 18.10, GetEntityCoords(ped)) < 5.0 then
      isDisplayable = false
      TriggerEvent("nui:display", false)
    end
  end
end)

I know it’s a disaster, by the way

I think I could use CancelEvent around these lines:

else
   TriggerEvent("nui:display", false)
   isDisplayable = true
   exports['progressBars']:closeUI()

but then I’d have to call the whole carwash thing an event and to be honest I don’t have any idea how

LATE LATE EDIT:
I added CancelEvent() there and now it is all solved. Do you think there could be a problem ?

LATE LATE LATE EDIT:
It didn’t work. I am stupid.

well i see a bunch of problems
just use my method

exports['progressBars']:startUI(25000, "We're washing your car")
Citizen.CreateThread(function()
    local timer = 0

    while timer < 25000 do
        Wait(100)
        timer = timer + 100
        local dist = #(GetEntityCoords(entity) - yourPosToCheckDistance)
        if dist > yourRadiusYouAreChecking then
            return functionThatShouldRunIfCheckIsFailed()
        end
    end

   functionThatShouldRunIfEverythingIsOk()
end)
1 Like

if you dont understand, ill explain
while loop will block the code that goes after it

if check is failed, then the function stops and functionThatShouldRunIfEverythingIsOk will never be called

1 Like

Imma be honest I am getting brain bsod while trying to convert mine to yours :sweat_smile:

aaaaaaaaa

A Wait(n) won’t necessarily wait n msec. It may wait more than that, as it’s aligned to frames.

Try something like this instead:

local timer = GetGameTimer()

repeat
    Wait(100)
until (GetGameTimer() - timer) > 25000
2 Likes

I tried everything I could and I still can’t find why the washStart function is not executed, no errors at all…
I tried both ideas, the fault is on my end ofcourse…

-- Events
local player = PlayerPedId()
local shownuicoords = vector3(-699.67, -933.01, 18.10)
Citizen.CreateThread(function()

while true do
Citizen.Wait(500)

local playerpos = GetEntityCoords(player)
local isinVeh = IsPedInAnyVehicle(player, true)
local checkposcar = GetDistanceBetweenCoords(shownuicoords.x, shownuicoords.y, shownuicoords.z, playerpos)

  if checkposcar < 5.0 and isinVeh then
    TriggerEvent("carwashnui:display", true)
  else
    TriggerEvent("carwashnui:display", false)
  end
end

end)

local washkey = IsControlJustReleased(0, 18)
local getvehicle = GetVehiclePedIsIn(player, false)
local playerpos = GetEntityCoords(player)
local checkposcar = GetDistanceBetweenCoords(shownuicoords.x, shownuicoords.y, shownuicoords.z, playerpos)
local isinVeh = IsPedInAnyVehicle(player, true)

function washStart()
 if washkey and checkposcar() < 5.0 and isinVeh then
  exports['progressBars']:startUI(25000, "We're washing your car")
  TriggerEvent("carwashnui:display", false)
  SetVehicleDirtLevel(getvehicle, 0.0)
  TriggerEvent('chat:addMessage', { args = {"We've washed your car!"} })
 end
end

function washStop()
  exports['progressBars']:closeUI()
end

--[[ I also tried this one
 Citizen.CreateThread(function()
    local timer = 0

    while timer < 25000 do
        Wait(100)
        timer = timer + 100
        if checkposcar > 5.0 then
            return washStop()
        end
    end

   washStart()
end)
--]]

Citizen.CreateThread(function()
  local timer = GetGameTimer()

  repeat
    Wait(100)
  until (GetGameTimer() - timer) > 25000
  if checkposcar > 5.0 then
    return washStop()
  else
    washStart()
  end
end)
Citizen.CreateThread(function()
  local timer = GetGameTimer()
  washStart()
  repeat
    Wait(100)

    if checkposcar > 5.0 then
      return washStop()
    end
  until (GetGameTimer() - timer) > 25000
    
  end
end)
1 Like

So weird. It still doesn’t trigger washStart()

local player = PlayerPedId()
local shownuicoords = vector3(-699.67, -933.01, 18.10)
Citizen.CreateThread(function()

while true do
Citizen.Wait(500)

local playerpos = GetEntityCoords(player)
local isinVeh = IsPedInAnyVehicle(player, true)
local checkposcar = GetDistanceBetweenCoords(shownuicoords.x, shownuicoords.y, shownuicoords.z, playerpos)

  if checkposcar < 5.0 and isinVeh then
    TriggerEvent("carwashnui:display", true)
  else
    TriggerEvent("carwashnui:display", false)
  end
end

end)

local washkey = IsControlJustReleased(0, 18)
local getvehicle = GetVehiclePedIsIn(player, false)
local playerpos = GetEntityCoords(player)
local checkposcar = GetDistanceBetweenCoords(shownuicoords.x, shownuicoords.y, shownuicoords.z, playerpos)
local isinVeh = IsPedInAnyVehicle(player, true)

function washStart()
 if washkey and checkposcar() < 5.0 and isinVeh then
  exports['progressBars']:startUI(25000, "We're washing your car")
  TriggerEvent("carwashnui:display", false)
  SetVehicleDirtLevel(getvehicle, 0.0)
  TriggerEvent('chat:addMessage', { args = {"We've washed your car!"} })
 end
end

function washStop()
  exports['progressBars']:closeUI()
end

Citizen.CreateThread(function()
  local timer = GetGameTimer()
  washStart()
  repeat
    Wait(100)

    if checkposcar > 5.0 then
      return washStop()
    end
  until (GetGameTimer() - timer) > 25000
    
end)

try this, i cant check it rn


local RADIUS_NUI = 5.0
local RADIUS_VEHICLE = 5.0
local SHOW_NUI_POSITION = vector3(-699.67, -933.01, 18.10)

local PlayerPedId = PlayerPedId
local GetEntityCoords = GetEntityCoords
local IsPedInAnyVehicle = IsPedInAnyVehicle
local TriggerEvent = TriggerEvent
local IsControlJustReleased = IsControlJustReleased
local GetVehiclePedIsIn = GetVehiclePedIsIn
local Wait = Wait
local GetGameTimer = GetGameTimer
local SetVehicleDirtLevel = SetVehicleDirtLevel





local playerPed = PlayerPedId()
local canStartWashingCar = false
local isWashingCar = false

local function stopWashingCar()
    isWashingCar = false
    exports['progressBars']:closeUI()
end

local function setCanStartWashingCar(flag)
    canStartWashingCar = flag
    TriggerEvent("carwashnui:display", flag)
end

-- check pos thread
Citizen.CreateThread(function()
    while true do
        Wait(500)
        playerPed = PlayerPedId()
        pos = GetEntityCoords(playerPed)
        local isInVeh = IsPedInAnyVehicle(playerPed, true)
        if not canStartWashingCar then
            if #(SHOW_NUI_POSITION - pos) < RADIUS_NUI and isInVeh then
                setCanStartWashingCar(true)
            end
        else
            if #(SHOW_NUI_POSITION - pos) >= RADIUS_NUI or not isInVeh then
                setCanStartWashingCar(false)
            end
        end
    end
end)

local function finishWashingCar(veh)
    SetVehicleDirtLevel(veh, 0.0)
    TriggerEvent('chat:addMessage', { args = {"We've washed your car!"} })
end

-- start washing and if everything is ok then just finish washing, else stop washing
local function startWashingCar(veh)
    isWashingCar = true
    exports['progressBars']:startUI(25000, "We're washing your car")
    TriggerEvent("carwashnui:display", false)
    Citizen.CreateThread(function()
        local timer = GetGameTimer()
        while isWashingCar and ((GetGameTimer() - timer) > 25000) do
            Wait(100)
            local dist = #(pos - GetEntityCoords(veh))
            if dist > RADIUS_VEHICLE then
                return stopWashingCar()
            end
        end
        finishWashingCar(veh)
    end)
end


-- check veh and control pressed thread
Citizen.CreateThread(function()
    while true do
        Wait(5)
        if canStartWashingCar and not isWashingCar then
            local veh = GetVehiclePedIsIn(playerPed, false)
            if veh and IsControlJustReleased(0, 18) then
                startWashingCar(veh)
            end
        end
        if not canStartWashingCar and isWashingCar then
            stopWashingCar()
        end
    end
end)
1 Like

Thank you qq_strike it does not work but it must be something on my end, I reverted it to the original one and I’ll leave it like this. XD

-- Locals

local player = PlayerPedId()

local vehicle = GetVehiclePedIsIn(player, false)

local isDisplayable = true

local isinVeh = IsPedSittingInAnyVehicle

local dist = GetDistanceBetweenCoords

local getkey = IsControlJustPressed

local playercoords = GetEntityCoords

local washsuccess = SetVehicleDirtLevel

-- Show NUI

Citizen.CreateThread(function()

  while true do

    Citizen.Wait(1)

    if dist(-699.67, -933.01, 18.10, GetEntityCoords(player)) < 5.0 and isinVeh(player) then

      if isDisplayable then

       TriggerEvent("carwashnui:display", true)

      end

    else

      TriggerEvent("carwashnui:display", false)

      isDisplayable = true

      exports['progressBars']:closeUI()

    end

  end

end)

-- Event

Citizen.CreateThread(function()

  while true do

    Citizen.Wait(1)

if getkey(0, 18) and dist(-699.67, -933.01, 18.10, GetEntityCoords(player)) < 5.0 and isinVeh(player) then

  isDisplayable = false

  TriggerEvent("carwashnui:display", false)

  exports['progressBars']:startUI(25000, "We're washing your car")

  Citizen.Wait(25000)

  if dist(-699.67, -933.01, 18.10, playercoords(player)) < 5.0 and isinVeh(player) then

    washsuccess(vehicle, 0.0)

  end

elseif getkey(0, 177) then

  isDisplayable = false

  TriggerEvent("carwashnui:display", false)

  exports['progressBars']:closeUI()

end

  end

end)
1 Like