-- $Revision: 194 $ -- Cauldron shopping list functions CauldronShopping = {}; local L = LibStub("AceLocale-3.0"):GetLocale("Cauldron") --[[ list = { ["<requestor>"] = { ["<item name>"] = <quantity>, ["<item name>"] = <quantity>, ... }, ["<requestor>"] = { ... }, }; --]] function CauldronShopping:NewList() local list = {}; return list; end function CauldronShopping:AddToList(list, requestor, itemName, quantity) -- sanity checks if (not list) and (not requestor) and (not itemName) then Cauldron:error("No shopping list available!"); return; end quantity = math.max(1, tonumber(quantity) or 1); if not list[requestor] then -- initialize the list for the requestor list[requestor] = {}; end if list[requestor][itemName] then list[requestor][itemName] = list[requestor][itemName] + quantity; else list[requestor][itemName] = quantity; end end function CauldronShopping:RemoveFromList(list, requestor, itemName, quantity) -- sanity checks if not list then Cauldron:error("No shopping list available!"); return -1; end if not list[requestor] then -- initialize the list for the requestor list[requestor] = {}; end local numRemoved = 0; if list[requestor][itemName] then if quantity then local origQty = list[requestor][itemName]; list[requestor][itemName] = list[requestor][itemName] - quantity; numRemoved = quantity; if list[requestor][itemName] < 1 then numRemoved = origQty; list[requestor][itemName] = nil; end else numRemoved = list[requestor][itemName]; list[requestor][itemName] = nil; end end return numRemoved; end function CauldronShopping:GetRequestors(list) if not list then Cauldron:error("No shopping list available!"); return; end local requestors = {}; for name, _ in pairs(list) do table.insert(requestors, name); end return requestors; end function CauldronShopping:ContainsItems(list) if not list then Cauldron:warn("CauldronShopping:ContainsItems: missing list!"); return false; end for _, items in pairs(list) do for _, amount in pairs(items) do if amount > 0 then return true; end end end return false; end function CauldronShopping:HasItems(list, requestor) if not list then Cauldron:warn("CauldronShopping:HasItems: missing list!"); return false; end if list[requestor] then for _, amount in pairs(list[requestor]) do if amount > 0 then return true; end end end return false; end function CauldronShopping:GetRequestedItems(list, requestor) if not list then Cauldron:warn("CauldronShopping:HasItems: missing list!"); return false; end if list[requestor] then return list[requestor]; end return {}; end function CauldronShopping:EmptyShoppingList(list, requestor) if not list then Cauldron:warn("CauldronShopping:EmptyShoppingList: missing list!"); return; end for r, _ in pairs(list) do if requestor then if requestor == r then list[r] = nil; end else list[r] = nil; end end end function CauldronShopping:AutoBuyShoppingItems(list, requestor) if not list then Cauldron:warn("CauldronShopping:AutoBuyShoppingItems: missing list!"); return; end local merchant = Cauldron:GetMerchantItems(); --[[ -- TODO: remove -- store merchant items in the DB if not Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant then Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant = {}; end for item, info in pairs(merchant) do Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant[item] = info; end --]] -- iterate over shopping list if list[requestor] then for item, amount in pairs(list[requestor]) do -- check if the merchant has the item and it can be purchased if merchant[item] then -- check if the toon has enough of the item already -- local counts = Cauldron:ReagentCount(item); -- if counts.total < amount then CauldronShopping:BuyItem(item, merchant[item], amount); -- amount - counts.total -- end end end end end function CauldronShopping:BuyItem(item, merchInfo, amount) if (not merchInfo) or (not amount) then Cauldron:warn("CauldronShopping:BuyItem: missing merchant item info or invalid amount!"); return; end if amount < 1 then -- just return with an error return; end -- figure out how many to purchase, accounting for stacks local stacks = 1; local purchases = 1; local tempAmount = amount; Cauldron:debug("tempAmount="..tostring(tempAmount)); local maxStack = 1; if amount > 1 then Cauldron:debug("item="..tostring(item)); _,_,_,_,_,_,_,maxStack = GetItemInfo(item); Cauldron:debug("maxStack="..tostring(maxStack)); if maxStack then purchases = ceil((amount / maxStack) / merchInfo.quantity); Cauldron:debug("purchases="..tostring(purchases)); else maxStack = 1; Cauldron:debug("setting maxStack to 1"); end --[[ i="Arcane Powder" o=40-GetItemCount(i) b=o _,_,_,_,_,_,_,s=GetItemInfo(i) for c=1,GetMerchantNumItems() do n,_,_,q=GetMerchantItemInfo(c) if n==i then for r=1,ceil((o/s)/q) do BuyMerchantItem(c,b>=s and s/q or ceil(b/q)) b=b-s end end end --]] end local total = purchases * merchInfo.quantity; Cauldron:debug("total="..tostring(total)); local qtyInfo = string.format(L["(%1$d total)"], total); Cauldron:debug("qtyInfo="..tostring(qtyInfo)); if purchases > 1 then qtyInfo = string.format(L["(%1$d stacks, %2$d total)"], purchases, total); Cauldron:debug("qtyInfo="..tostring(qtyInfo)); end -- tell the user, because that's the right thing to do Cauldron:Print(string.format(L["Purchasing %1$s from merchant %2$s..."], item, qtyInfo)); -- buy the items for i=1,purchases do stacks = tempAmount >= maxStack and maxStack / merchInfo.quantity or ceil(tempAmount / merchInfo.quantity); Cauldron:debug("stacks="..tostring(stacks)); BuyMerchantItem(merchInfo.index, stacks); tempAmount = tempAmount - maxStack; Cauldron:debug("tempAmount="..tostring(tempAmount)); end end