diff --git a/cache.lua b/cache.lua index 89bb60e..a97c6f3 100644 --- a/cache.lua +++ b/cache.lua @@ -63,12 +63,12 @@ function public.item_id(item_name) end function private.scan_merchant() - Aux.util.loop_inventory(function(bag, slot) - local item_info = Aux.info.container_item(bag, slot) + for slot in Aux.util.inventory() do + local item_info = Aux.info.container_item(unpack(slot)) if item_info then aux_merchant_sell[item_info.item_id] = item_info.tooltip.money / item_info.aux_quantity end - end) + end -- TODO maybe more detail? zone or local merchant_name = UnitName('npc') local merchant_item_count = GetMerchantNumItems() diff --git a/core.lua b/core.lua index 6716c79..db2652a 100644 --- a/core.lua +++ b/core.lua @@ -1,5 +1,5 @@ Aux = { - version = '2.9.17', + version = '2.9.18', blizzard_ui_shown = false, orig = {}, } diff --git a/post.lua b/post.lua index e3c2dbc..fa92c5c 100644 --- a/post.lua +++ b/post.lua @@ -9,52 +9,54 @@ function private.process() state.allow_partial = false end - local stacking_complete - local stack_slot - + local stacking_complete, target_slot + Aux.stack.start( state.item_key, state.stack_size, function(slot) stacking_complete = true - stack_slot = slot + target_slot = slot end ) - Aux.control.wait_until(function() return stacking_complete end, function() - - if stack_slot and Aux.info.container_item(stack_slot.bag, stack_slot.bag_slot).aux_quantity <= state.stack_size then - private.post_auction(stack_slot, function(stack_size) - if state.posted == state.count then - state.partial_stack = stack_size - end - state.posted = state.posted + 1 - return private.process() - end) + return Aux.control.wait_until(function() return stacking_complete end, function() + if target_slot then + return private.post_auction(target_slot, state.posted == state.count, private.process) else return public.stop() end - end) + end + + return public.stop() +end + +function private.post_auction(slot, partial, k) + local item_info = Aux.info.container_item(unpack(slot)) + if item_info.item_key == state.item_key and Aux.info.auctionable(item_info.tooltip) and (item_info.aux_quantity == state.stack_size or partial and item_info.aux_quantity < state.stack_size) then + + ClearCursor() + ClickAuctionSellItemButton() + ClearCursor() + PickupContainerItem(unpack(slot)) + ClickAuctionSellItemButton() + ClearCursor() + + StartAuction(max(1, Aux.round(state.unit_start_price * item_info.aux_quantity)), Aux.round(state.unit_buyout_price * item_info.aux_quantity), state.duration) + Aux.control.wait_until(function() return not GetContainerItemInfo(unpack(slot)) end, function() + if state.posted == state.count then + state.partial_stack = item_info.aux_quantity + end + state.posted = state.posted + 1 + return k() + end) + else return public.stop() end end -function private.post_auction(slot, k) - ClearCursor() - ClickAuctionSellItemButton() - ClearCursor() - PickupContainerItem(slot.bag, slot.bag_slot) - ClickAuctionSellItemButton() - ClearCursor() - local stack_size = Aux.info.container_item(slot.bag, slot.bag_slot).aux_quantity - StartAuction(max(1, Aux.round(state.unit_start_price * stack_size)), Aux.round(state.unit_buyout_price * stack_size), state.duration) - Aux.control.wait_until(function() return not GetContainerItemInfo(slot.bag, slot.bag_slot) end, function() - return k(stack_size) - end) -end - function public.stop() if state then Aux.control.kill_thread(state.thread_id) diff --git a/post_frame.lua b/post_frame.lua index 1c2735a..f7551a9 100644 --- a/post_frame.lua +++ b/post_frame.lua @@ -747,20 +747,15 @@ function private.quantity_update() end function private.unit_vendor_price(item_key) - local inventory_iterator = Aux.util.inventory_iterator() - while true do - local slot = inventory_iterator() - if not slot then - break - end + for slot in Aux.util.inventory() do - local item_info = Aux.info.container_item(slot.bag, slot.bag_slot) + local item_info = Aux.info.container_item(unpack(slot)) if item_info and item_info.item_key == item_key then if Aux.info.auctionable(item_info.tooltip, nil, item_info.lootable) then ClearCursor() - PickupContainerItem(slot.bag, slot.bag_slot) + PickupContainerItem(unpack(slot)) ClickAuctionSellItemButton() local auction_sell_item = Aux.info.auction_sell_item() ClearCursor() @@ -828,14 +823,9 @@ function private.update_inventory_records() local auction_candidate_map = {} - local inventory_iterator = Aux.util.inventory_iterator() - while true do - local slot = inventory_iterator() - if not slot then - break - end + for slot in Aux.util.inventory() do - local item_info = Aux.info.container_item(slot.bag, slot.bag_slot) + local item_info = Aux.info.container_item(unpack(slot)) if item_info then local charge_class = item_info.charges or 0 diff --git a/scan.lua b/scan.lua index c31f60e..392fbe6 100644 --- a/scan.lua +++ b/scan.lua @@ -231,8 +231,8 @@ function private.submit_query(k) private.wait_for_results(function() local _, total_count = GetNumAuctionItems(private.current_thread().params.type) private.current_thread().total_pages = math.ceil(total_count / PAGE_SIZE) - if private.current_thread().total_pages >= private.current_thread().page + 1 then - private.wait_for_callback(private.current_thread().params.on_page_loaded, private.current_thread().page, private.current_thread().total_pages, function() + if max(1, private.current_thread().total_pages) >= private.current_thread().page + 1 then + private.wait_for_callback(private.current_thread().params.on_page_loaded, private.current_thread().page, max(1, private.current_thread().total_pages), function() return k() end) else diff --git a/stack.lua b/stack.lua index e41de79..505a9ab 100644 --- a/stack.lua +++ b/stack.lua @@ -3,95 +3,103 @@ Aux.stack = public local state -function private.item_slots(item_key) - local slots = Aux.util.inventory_iterator() - return function() - local slot - repeat - slot = slots() - until slot == nil or private.item_key(slot) == item_key - return slot - end +function private.stack_size(slot) + local container_item_info = Aux.info.container_item(unpack(slot)) + return container_item_info and container_item_info.count or 0 end -function private.find_empty_slot() - for slot in Aux.util.inventory_iterator() do - if not GetContainerItemInfo(slot.bag, slot.bag_slot) then +function private.charges(slot) + local container_item_info = Aux.info.container_item(unpack(slot)) + return container_item_info and container_item_info.charges +end + +function private.max_stack(slot) + local container_item_info = Aux.info.container_item(unpack(slot)) + return container_item_info and container_item_info.max_stack +end + +function private.locked(slot) + local container_item_info = Aux.info.container_item(unpack(slot)) + return container_item_info and container_item_info.locked +end + +function private.find_item_slot(partial) + for slot in Aux.util.inventory() do + if private.matching_item(slot, partial) and not Aux.util.table_eq(slot, state.target_slot) then return slot end end end -function private.find_charges_item_slot(item_key, charges) - for slot in private.item_slots(item_key) do - if private.item_charges(slot) == charges then +function private.matching_item(slot, partial) + local item_info = Aux.info.container_item(unpack(slot)) + return item_info and item_info.item_key == state.item_key and Aux.info.auctionable(item_info.tooltip) and (not partial or item_info.count < item_info.max_stack) +end + +function private.find_empty_slot() + for slot, type in Aux.util.inventory() do + if type == 1 and not GetContainerItemInfo(unpack(slot)) then + return slot + end + end +end + +function private.find_charge_item_slot() + for slot in private.item_slots(state.item_key) do + if private.charges(slot) == state.target_size then return slot end end end function private.move_item(from_slot, to_slot, amount, k) - local size_before = private.stack_size(to_slot) - + + if private.locked(from_slot) or private.locked(to_slot) then + return Aux.control.wait(k) + end + amount = min(private.max_stack(from_slot) - private.stack_size(to_slot), private.stack_size(from_slot), amount) + local expected_size = private.stack_size(to_slot) + amount ClearCursor() - SplitContainerItem(from_slot.bag, from_slot.bag_slot, amount) - PickupContainerItem(to_slot.bag, to_slot.bag_slot) - - return Aux.control.wait_until(function() return private.stack_size(to_slot) == size_before + amount end, k) -end + SplitContainerItem(from_slot[1], from_slot[2], amount) + PickupContainerItem(unpack(to_slot)) -function private.item_key(slot) - local container_item_info = Aux.info.container_item(slot.bag, slot.bag_slot) - return container_item_info and container_item_info.item_key -end - -function private.stack_size(slot) - local container_item_info = Aux.info.container_item(slot.bag, slot.bag_slot) - return container_item_info and container_item_info.count or 0 -end - -function private.item_charges(slot) - local container_item_info = Aux.info.container_item(slot.bag, slot.bag_slot) - return container_item_info and container_item_info.charges + return Aux.control.wait_until(function() return private.stack_size(to_slot) == expected_size end, k) end function private.process() + if not state.target_slot or not private.matching_item(state.target_slot) then + state.target_slot = private.find_item_slot() + if not state.target_slot then + return public.stop() + end + end + + if private.charges(state.target_slot) then + state.target_slot = private.find_charge_item_slot() + return public.stop() + end + if private.stack_size(state.target_slot) > state.target_size then - local empty_slot = private.find_empty_slot() - - if empty_slot then + local slot = private.find_item_slot(true) or private.find_empty_slot() + if slot then return private.move_item( state.target_slot, - empty_slot, + slot, private.stack_size(state.target_slot) - state.target_size, - function() - return private.process() - end) - else - local next_slot = state.other_slots() - if next_slot then - return private.move_item( - state.target_slot, - next_slot, - private.stack_size(state.target_slot) - state.target_size, - function() - return private.process() - end) - end + private.process + ) end elseif private.stack_size(state.target_slot) < state.target_size then - local next_slot = state.other_slots() - if next_slot then + local slot = private.find_item_slot() + if slot then return private.move_item( - next_slot, + slot, state.target_slot, state.target_size - private.stack_size(state.target_slot), - function() - return private.process() - end + private.process ) end end @@ -99,16 +107,14 @@ function private.process() return public.stop() end -function private.max_stack(slot) - local container_item_info = Aux.info.container_item(slot.bag, slot.bag_slot) - return container_item_info and container_item_info.max_stack -end - function public.stop() if state then Aux.control.kill_thread(state.thread_id) local callback, slot = state.callback, state.target_slot + if not private.matching_item(slot) then + slot = nil + end state = nil @@ -121,23 +127,12 @@ end function public.start(item_key, size, callback) public.stop() - local slots = private.item_slots(item_key) - local target_slot = slots() - local thread_id = Aux.control.new_thread(private.process) state = { thread_id = thread_id, + item_key = item_key, target_size = size, - target_slot = target_slot, - other_slots = slots, callback = callback, } - - if not target_slot then - public.stop() - elseif private.item_charges(target_slot) then - state.target_slot = private.find_charges_item_slot(item_key, size) - public.stop() - end end \ No newline at end of file diff --git a/tooltip.lua b/tooltip.lua index 1b0e720..5ba4387 100644 --- a/tooltip.lua +++ b/tooltip.lua @@ -239,15 +239,11 @@ end function game_tooltip_hooks:SetAuctionSellItem() local name, _, quantity, _, _, _ = GetAuctionSellItemInfo() if name then - for bag = 0, 4 do - if GetBagName(bag) then - for slot = 1, GetContainerNumSlots(bag) do - local link = GetContainerItemLink(bag, slot) - if link and ({Aux.info.parse_hyperlink(link)})[5] == name then - private.extend_tooltip(GameTooltip, link, quantity) - return - end - end + for slot in Aux.util.inventory() do + local link = GetContainerItemLink(unpack(slot)) + if link and ({Aux.info.parse_hyperlink(link)})[5] == name then + private.extend_tooltip(GameTooltip, link, quantity) + return end end end diff --git a/util.lua b/util.lua index 548fafa..c1f34b3 100644 --- a/util.lua +++ b/util.lua @@ -9,11 +9,16 @@ function public.id(object) end function public.table_eq(t1, t2) + if not t1 or not t2 then + return false + end + for key, value in t1 do if t2[key] ~= value then return false end end + return true end @@ -46,32 +51,38 @@ function public.trim(string) return string end -function Aux.util.inventory_iterator() - local inventory = {} - for bag = 0, 4 do - if GetBagName(bag) then - for bag_slot = 1, GetContainerNumSlots(bag) do - tinsert(inventory, { bag = bag, bag_slot = bag_slot }) - end - end - end +function public.inventory() + local bag, slot = 0, 0 - local i = 0 - local n = getn(inventory) - return function() - i = i + 1 - if i <= n then - return inventory[i] - end - end + return function() + if not GetBagName(bag) or slot >= GetContainerNumSlots(bag) then + repeat + bag = bag + 1 + until GetBagName(bag) or bag > 4 + slot = 1 + else + slot = slot + 1 + end + + if bag <= 4 then + return { bag, slot }, public.bag_type(bag) + end + end end -function public.loop_inventory(f) - for bag = 0, 4 do - if GetBagName(bag) then - for slot = 1, GetContainerNumSlots(bag) do - f(bag, slot) - end +do + local bag_types = { GetAuctionItemSubClasses(3) } + + function public.bag_type(bag) + if bag == 0 then + return 1 + end + + local link = GetInventoryItemLink('player', ContainerIDToInventoryID(bag)) + if link then + local item_id = Aux.info.parse_hyperlink(GetInventoryItemLink('player', ContainerIDToInventoryID(bag))) + local item_info = Aux.info.item(item_id) + return Aux.item_subclass_index(3, item_info.subclass) end end end