Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.

while (NeedCount > 0) do
mq.doevents()
mq.delay(100)
NeedCount =ItemAmount- mq.TLO.FindItemCount(ItemID)()
mq.delay(100)
if (NeedCount <=0) then return end
--Click Buy
mq.cmd('/notify MerchantWnd MW_Buy_Button leftmouseup')
mq.delay (500)
and this ain't even hard math..
return is for functions, break is for loops. But your logic looks like you have two different conditions determining what you should do (greater than zero versus zero inclusive).
I’d suggest reworking the logic.
NeedCount=ItemAmount-mq.TLO.FindItemCount(ItemID)()
while (NeedCount > 0) do
mq.doevents()
mq.delay(100)
NeedCount = ItemAmount- mq.TLO.FindItemCount(ItemID)()
mq.delay(100)
--Click Buy
mq.cmd('/notify MerchantWnd MW_Buy_Button leftmouseup')
mq.delay (500)
--change to break out..
if (mq.TLO.Window('MerchantWnd').Child('MW_Buy_Button').Enabled() ~= true) then print ("out of cash") return false end
mq.delay(500)
if (NeedCount < 100) then
--Use Quantity Slider
mq.delay(500)
--select qty..
mq.cmd('/notify QuantityWnd QTYW_slider newvalue',NeedCount)
mq.delay(500)
end
mq.delay(500)
--Click Accept
mq.cmd('/nomodkey /notify QuantityWnd QTYW_Accept_Button leftmouseup')
mq.delay(1000)
-- Calculate Remaining
NeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)()
mq.delay(500)
mq.doevents()
end
--end do
local NeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)()
while NeedCount > 0 do
mq.doevents()
--Click Buy
mq.cmd('/notify MerchantWnd MW_Buy_Button leftmouseup')
mq.delay(500)
--change to break out..
if mq.TLO.Window('MerchantWnd').Child('MW_Buy_Button').Enabled() ~= true then
print("out of cash")
NeedCount = 0
else
if NeedCount < 100 then
--Use Quantity Slider
--select qty..
mq.cmd('/notify QuantityWnd QTYW_slider newvalue', NeedCount)
end
--Click Accept
mq.cmd('/nomodkey /notify QuantityWnd QTYW_Accept_Button leftmouseup')
-- wait for quantity to change
mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end)
-- Calculate Remaining
local newNeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)()
if newNeedCount == NeedCount then
NeedCount = 0
print('Failed to update quantity?')
else
NeedCount = newNeedCount
end
end
end
--end do
So I found this very hard to read because the formatting is all over the place.
You should clean up your formatting. It really helps to understand whats going on. The indentation helps show you structure of things like while loops.
you could do something like this to check that the quantity actually changes
Lua:local NeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)() while NeedCount > 0 do mq.doevents() --Click Buy mq.cmd('/notify MerchantWnd MW_Buy_Button leftmouseup') mq.delay(500) --change to break out.. if mq.TLO.Window('MerchantWnd').Child('MW_Buy_Button').Enabled() ~= true then print("out of cash") NeedCount = 0 else if NeedCount < 100 then --Use Quantity Slider --select qty.. mq.cmd('/notify QuantityWnd QTYW_slider newvalue', NeedCount) end --Click Accept mq.cmd('/nomodkey /notify QuantityWnd QTYW_Accept_Button leftmouseup') -- wait for quantity to change mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end) -- Calculate Remaining local newNeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)() if newNeedCount == NeedCount then NeedCount = 0 print('Failed to update quantity?') else NeedCount = newNeedCount end end end --end do
mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end)
Code:mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end)
This will wait 5 seconds or until it updates, whichever is faster of the two..
This is better than my wait 1 second or whatever and pray...
At which point the do while should break out.. If it takes longer than 5 seconds then it is a lag issue I surmise..
In other news, I am looking for a code formatter for Notepad++ for Lua.. the inefficient and current way is to put in comments so I know what is doing what and where..
Or bump it up to 30000 and let lag be lag. You'll still catch it with the condition and go on as soon as you can.
This was my thought.. because "damn the torpedoes full speed ahead"
Check out Visual Studio Code. It's free, you can add Lua syntax highlighting and debug support, and it'll help with the formatting.
I will take a look

mq.delay (30000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end)
start_inv = mq.TLO.Me.FreeInventory()
mq.cmd('/nomodkey /notify QuantityWnd QTYW_Accept_Button leftmouseup')
while start_inv == mq.TLO.Me.FreeInventory() do
mq.delay(1000)
end
start_inv =0
local pack = mq.TLO.FindItem('container name').ItemSlot() - 22
-- for each item in the recipe, put an item in the (next) pack slot
for pack_slot = 1, recipe_count do
-- do something here to pick up the item
-- mq.cmdf('/itemnotify "%s"', item_to_pickup)
-- and then put the item in the container
local cmd = string.format('/nomodkey /itemnotify in pack%s %s leftmouseup', pack, pack_slot)
print(cmd)
mq.cmd(cmd)
end
You should use better variable names. Future you will thank past you in a few months once these are all working.
Code:local pack = mq.TLO.FindItem('container name').ItemSlot() - 22 -- for each item in the recipe, put an item in the (next) pack slot for pack_slot = 1, recipe_count do -- do something here to pick up the item -- mq.cmdf('/itemnotify "%s"', item_to_pickup) -- and then put the item in the container local cmd = string.format('/nomodkey /itemnotify in pack%s %s leftmouseup', pack, pack_slot) print(cmd) mq.cmd(cmd) end
mq.cmd('/nomodkey /itemnotify in pack7 1 leftmouseup ')
mq.cmd('/nomodkey /itemnotify in pack'"..F.."' '"..X.."' leftmouseup ')
I actually just figured it out.. or at least a way.. but your way is fancy
My Way:
Code:mq.cmd('/nomodkey /itemnotify in pack7 1 leftmouseup ')
Code:for x = 0 , 3 do mq.cmd('/ctrl /itemnotify "${FindItem["'..scooby..'"]}" leftmouseup') local F = mq.TLO.FindItem(containername).ItemSlot() - 22 --local Z = mq.TLO.FindItem(containername).ItemSlot2() + 1 ev = x + 1 mq.cmd('/nomodkey /itemnotify in pack"'..F..'" "'..ev..'" leftmouseup') mq.delay(200) end
I am doing a lot more documenting this go around than I did last time.local component = mq.TLO.FindItem(scooby).ItemSlot()
local container = mq.TLO.FindItem(containername).ItemSlot()
if component > container then print "no workie" end
[code]
That code is looking great!
while not mq.TLO.Merchant.Open() do mq.delay(100) end
repeat mq.delay(100) until mq.TLO.Merchant.Open()
mq.delay(10000, function() return mq.TLO.Merchant.Open() end)
its supposed to wait until the number of items changes.
mq.delay(30000, function() return ItemAmount - mq.TLO.FindItemCount(l_ItemID)() ~= NeedCount end)
mq.delay(<some giant number>, function() end) in most cases because I don't see a lot of folks actually accounting for the case where the delay times out and the "thing they were waiting on" didn't do what it was supposed to - be it a window refresh, some value changing, some item appearing, etc. my example somewhere in this thread where I introduced the delay did check for failure
-- wait for quantity to change
mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end)
-- Calculate Remaining
local newNeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)()
if newNeedCount == NeedCount then
NeedCount = 0
print('Failed to update quantity?')
else
NeedCount = newNeedCount
end
Code:-- wait for quantity to change mq.delay(5000, function() return ItemAmount - mq.TLO.FindItemCount(ItemID)() ~= NeedCount end) -- Calculate Remaining local newNeedCount = ItemAmount - mq.TLO.FindItemCount(ItemID)() if newNeedCount == NeedCount then NeedCount = 0 print('Failed to update quantity?') else NeedCount = newNeedCount end
db_temp:exec("DROP TABLE IF EXISTS eTable")
db_temp:exec [[
CREATE TABLE IF NOT EXISTS eTable (
"ItemID" INTEGER,
"ItemName" TEXT,
"BuyCount" INTEGER,
"RecipeID" INTEGER,
"MakeCount" INTEGER
);]]

I'm not a fan of themq.delay(<some giant number>, function() end)in most cases because I don't see a lot of folks actually accounting for the case where the delay times out and the "thing they were waiting on" didn't do what it was supposed to - be it a window refresh, some value changing, some item appearing, etc.
If you use that pattern you have to say to yourself, well what if the time passes and what I expected to happen doesn't? Which means a bit more code to handle that gracefully or you'll just get a fat error about something not being there or whatnot.
To be fair, I don't like waiting a long time either. But lag is going to happen. TSC (the macro version) sometimes fails on certain vendors in PoK just because it didn't wait long enough.
I've omitted error checking in discussion just to get an answer to the immediate issue. However, you are correct that error checking to insure the expected condition is met is also important and necessary.
If it were not for bad luck I would have none at all.. I can get the SQLite to do what I want, until I loop to it again..
I tell it to drop the table, create the table, and insert the values, but it doesn't seem to wipe and create the table over.
for you DBAs out there.. adding mq.delays seem to have no effect, opening closing and re-opening the db also does not seem to work.. db:busy_timeout. .. still reading up on that..
the flow is:
drop table
create table
insert values
wait until cycle has completed and then loop to the top to write a new table with changes..
the sqlite statements I am using..
Code:db_temp:exec("DROP TABLE IF EXISTS eTable")
Code:db_temp:exec [[ CREATE TABLE IF NOT EXISTS eTable ( "ItemID" INTEGER, "ItemName" TEXT, "BuyCount" INTEGER, "RecipeID" INTEGER, "MakeCount" INTEGER );]]
because it's me, I am always doing something crazy.. so I am running this in the main program and trying to insert into in a called program. it always works the first time around but then conks out during subsequent runs.. as a test.. I provided an event that would cause it to update,, well it did,, about 10 seconds later.. weird
however.. I just tested using everything in the same program and it works like a champ ..
trying to wrap my head around prepared statements...
the plot congeals:
View attachment 32922
For SQL your pattern shouldn’t be to drop and recreate the table every time. The pattern for this should be something like storing metadata on your schema.
As an example, if the table doesn’t exist you create it and insert an entry telling you that it is version 1 (schema version 1). If it does exist, you query the version and see if you need to make changes to the table.
This allows you to continually update without breaking changes (or dropping the table).
All of that said it sounds like you are doing this transactionally and not ending your transaction.
local clean_string = string.gsub(p_raw_table[x], "'", '')
function return_string(str, int)
local counter = 0
for word in string.gmatch(str, '([^,]+)') do
counter = counter + 1
if counter == int then return word end
end
end
var_ItemCount = tonumber(return_string(clean_string, 3))
-- Determine delivery item need requirements
local l_need_count = deliver_item_req - deliver_item_cur
-- Determine On Hand Count
local rii = quest_row.Quest_Item_ID
local hc = mq.TLO.FindItemCount(rii)()
-- Troubleshooting
-- print("We have: ", hc, " We need: ", l_need_count, " Step: ",quest_row.Quest_Deliver_Step)
-- Determine Completion Status
if hc >= l_need_count then
print("BREAKING: STEP: ", quest_row.Quest_Deliver_Step,
" Ready For Turn in")
break
end
-- Check Recipe and Create Recipe List
local recipe_list, s = crunch.items(quest_row.Quest_Recipe_ID,
l_need_count, hc)
-- Determine If We Can Make The Recipe
soured = s
if soured == 0 then
print "BREAKING: Can't make it"
break
end
-- Create Shopping List
local raw_table = raw_item_list_table(recipe_list)
local shopping_list = final_shopping_list_table(raw_table)
-- Go Shopping
go_shopping(shopping_list)
mq.delay(500)
mq.cmd('/cleanup')
mq.delay(500)
-- Go Crafting
go_craft(recipe_list, 0)


Great News.. the need to destroy in Abysmal Sea, seems to have vanished. Before you would not get any new items until you destroyed the left overs.. now it wipes the left overs! Well this works on pottery will check others..

mq.event('RecipeWin', "#*#nuz says, 'You've#*#", ForceEnd)
mq.event('RecipeFan', "#*#nuz says, 'Fantastic#*#", ForceEnd)
Time to wear the dunce cap...
Why is this not working:
Code:mq.event('RecipeWin', "#*#nuz says, 'You've#*#", ForceEnd)
but this is:
Code:mq.event('RecipeFan', "#*#nuz says, 'Fantastic#*#", ForceEnd)
pro-tip: don't do this:
print (mq.event())
nevermind..
the events wouldn't do anything until I got the blue trade skill text... which is why it worked for everything but the final text.. which is perplexing in itself..
I looked at the drunkard stein macro events and it seems pretty straight forward.. but I am unable to get text to trigger for me...
while true do
mq.cmd('/doevents flush')
mq.delay(1000)
mq.cmd('/say help')
mq.doevents()
mq.delay(1000)
end
.. so I have to stop it and force it to loop and work off of the results..
