[SOLVED] Loop action after pressing a key

I’m editing this moneywash script to work better for my server. As it sits, you press E over and over to wash a certain amount of dirty money. I want to make a loop to continue washing money until there is none left. The person who released this has stated that they will not be helping/updating this (go figure). I have next to zero knowledge of LUA and I’m kind of learning as I go with editing scripts to how I want them, so please bear with me. :cry:

script snippet
RegisterServerEvent('esx_blackmoney:washMoney')
AddEventHandler('esx_blackmoney:washMoney', function()
	local _source = source
	local xPlayer = ESX.GetPlayerFromId(_source)
	local accountMoney = 0
	
	accountMoney = xPlayer.getAccount('black_money').money

	if accountMoney < 99 then
		notification('You do not have enough ~r~dirty money~s~ to wash')
	else
		xPlayer.removeAccountMoney('black_money', 100)
		xPlayer.addMoney(100)
		notification('You ~g~washed~s~ 100 ~r~dirty money')
	end
end)

How could I set this up to loop? I know of the different loop types, I just don’t know how to implement them into this script.

I would say you grab this “dirty money” variable then do a while loop that subtracts x amount then waits for x milliseconds. Break the while loop of you press any of the movement keys or something so that its cancelled OR if they are a certain distance away from the middle.

Pseudocode:

Dirtymoney=99
While dirtymoney does not equal 0:
If more than 10m away break
Take away 1 from dirty money
Wait 3 seconds 
1 Like

Thank you. I put together this: (you can ignore the pNotify parts)

	if accountMoney < 999 then
		-- pNotify
		TriggerClientEvent("pNotify:SendNotification", -1, {
            text = "You don't have enough dirty money to wash.",
            type = "error",
            queue = "lmao",
            timeout = 3000,
            layout = "centerLeft"
        })
	else
		TriggerClientEvent("pNotify:SendNotification", -1, {
            text = "Washing money...",
            type = "info",
            queue = "lmao",
            timeout = 3000,
            layout = "centerLeft"
        })
		-- Wash Loop
		while accountMoney > 999 do
			xPlayer.removeAccountMoney('black_money', 1000)
			xPlayer.addMoney(1000)
			Citizen.Wait(5000)
			if IsControlJustPressed(0, 32) or  --If player presses W, S, A, D, or E then stop washing
				IsControlJustPressed(0, 33) or
				IsControlJustPressed(0, 34) or
				IsControlJustPressed(0, 35) or
				IsControlJustPressed(0, 38) then
			break
			end
		end
	end

Would this be appropriate in achieving what I want to do?

Also, do you think just pressing E IsControlJustPressed(0, 38) to stop would suffice?

The way to handle breaking out is personal preference.

I think the code is like I imagined it to be. Go ahead and test it :slight_smile:

It works! Sort of… :sunglasses:

I added

  if accountMoney < 999 then
  --notification goes here
  break
  end

To replace a key being pressed, but when accountMoney is less than 999, the loop doesn’t break, it just gives negative dirty money in my account.

Am I putting break in the wrong place?

1 Like

I am still having issues with this. I just can’t figure out why the loop isn’t broken when accountMoney is less than 999…

where do you originally get accountMoney?

it’s likely a side-effect of a pattern called memoization

for example

local accountMoney = xPlayer.getDirtyMoney() – just guessing here

if that returns a “copy” of the variable containing the amount of money then when you call other methods on xPlayer like removeAccountMoney(‘black_money’, 1000) it is working with the original variable (probably a table member) and you’re accountMoney variable has a copy from a prior point in time, so it’s value is unaffected.

To fix you just need to set accountMoney again within the loop…

Or rather than using a reference call whatever function you called to get it originally in the while condition itself, instead, such as:

while xPlayer.getDirtyMoney() > 999

1 Like

accountMoney is a variable defined in the same function as the loop:

	local accountMoney = 0
	
	accountMoney = xPlayer.getAccount('black_money').money

However, I tried just as you said by putting

while xPlayer.getAccount('black_money').money do
--wash money
end

And bam! Worked flawlessly. Thanks a ton for that suggestion - it saved more of my hair being pulled out!

Hey guys, since for some reason i cant create new topic on my own, im gonna invade this one.
I’ve put together this

Citizen.CreateThread(function()
    while (GetDistanceBetweenCoords(GetEntityCoords(GetPlayerPed(-1)), -7.566, -662.183, 33.057, true) < 11.5)  do
       if IsPedArmed(GetPlayerPed(-1), 7) and IsPedArmed(GetPlayerPed(-1), 4) then
       SetEntityCoords(GetPlayerPed(-1), 14.566, -686.183, 32.34)
       ESX.ShowNotification('~g~Kicked out, no weapons!.')
       else Citizen.Wait(1000)
       end
       Citizen.Wait(1000
    end
end)

Its supposed to check for player in a certain area, and once he is in there and he has weapon equiped it teleports him away… now, i know there is something wrong, it only works once when im in the area and i restart the script, it teleports me away, but when i get back in, it wont teleport me again. And when i restart the script once outside the area, my game freezes.
Please help me.

1 Like

put a verifier, false / true and reset it when teleporting