vanilla-wow-addons – Rev 1
?pathlinks?
-- BuyEmAll - By Cogwheel v1.12 - See readme.txt
--[[Hook BuyMerchantItem for debugging purposes
function BuyMerchantItem(button, amount)
if not amount then amount = 1 end
print("Buying "..amount.." items.")
end --]]
-- Herb & Enchanting item lists courtesy of Periodic Table by Tekkub
BuyEmAll_SpecialItems = {
Herb = "3358 8839 13466 4625 13467 3821 785 13465 13468 2450 2452 3818 3355 3357 8838 3369 3820 8153 8836 13463 8845 8846 13464 2447 2449 765 2453 3819 3356 8831",
Enchant = "11083 16204 11137 11176 10940 11174 10938 11135 11175 16202 11134 16203 10998 11082 10939 11084 14343 11139 10978 11177 14344 11138 11178",
}
function BuyEmAllFrame_OnLoad()
-- Set up confirmation dialog
StaticPopupDialogs["BUYEMALL_CONFIRM"] = {
text = BUYEMALL_CONFIRMATION,
button1 = TEXT(YES),
button2 = TEXT(NO),
OnAccept = BuyEmAll_OnAccept,
timeout = 0,
hideOnEscape = true,
}
BuyEmAllStackButton.defaultText = BUYEMALL_STACK
BuyEmAllMaxButton.defaultText = BUYEMALL_MAX
-- Replace the SplitStack callback and for each merchant item button
for i=1,12 do
local button=getglobal("MerchantItem"..i.."ItemButton")
button.SplitStack = BuyEmAll_SplitStack
button:SetScript("OnHide", function()
if ( this.hasBuyEmAll == 1 ) then
BuyEmAllFrame:Hide();
end
end)
end
end
function BuyEmAllCostMoney_OnLoad()
MoneyTypeInfo["BUYEMALL"] = {
UpdateFunc = function() return this.staticMoney end,
showSmallerCoins = "Backpack",
fixedWidth = 1,
collapse = 0,
truncateSmallCoins = nil
}
this.small = 1
this.staticMoney = 0
MoneyFrame_SetType("BUYEMALL")
end
--[[ Since I have to control two different paths through this function, I just
recreated it here to make life a bit easier. ]]
function MerchantItemButton_OnClick(button, ignoreModifiers)
if ( MerchantFrame.selectedTab == 1 ) then
-- Is merchant frame
if ( button == "LeftButton" ) then
if ( IsControlKeyDown() and not ignoreModifiers ) then
DressUpItemLink(GetMerchantItemLink(this:GetID()));
elseif ( IsShiftKeyDown() and not ignoreModifiers ) then
if ( ChatFrameEditBox:IsVisible() ) then
ChatFrameEditBox:Insert(GetMerchantItemLink(this:GetID()));
else
BuyEmAll_ChooseAmount()
end
else
PickupMerchantItem(this:GetID());
end
else
if ( IsControlKeyDown() and not ignoreModifiers ) then
return;
elseif ( IsShiftKeyDown() and not ignoreModifiers ) then
BuyEmAll_ChooseAmount()
else
BuyMerchantItem(this:GetID());
end
end
else
-- Is buyback item
BuybackItem(this:GetID());
end
end
-- Courtesy of wowwiki.com
function GetItemInfoFromItemLink(link)
local itemId = nil;
if ( type(link) == "string" ) then
_,_, itemId = string.find(link, "item:(%d+):");
end
if ( itemId ) then
return itemId, GetItemInfo(itemId);
end
end
-- Figures out maximum purchase amount and shows the BuyEmAllFrame
function BuyEmAll_ChooseAmount()
local name, _, price, quantity, numAvailable = GetMerchantItemInfo(this:GetID());
this.presetStack = quantity
this.price = price
this.itemName = name
this.itemID, _,_,_,_,_, this.itemSubType, this.stackSize =
GetItemInfoFromItemLink(GetMerchantItemLink(this:GetID()))
local bagSpace, specialSpace = BuyEmAll_FreeSpace(name, itemID)
local specialMax = floor(specialSpace / quantity) * quantity
this.bagMax = floor(bagSpace / quantity) * quantity + specialMax
this.moneyMax = floor(GetMoney() / price) * quantity
this.available = numAvailable
local maxPurchase = min(this.bagMax, this.moneyMax)
if numAvailable ~= -1 then maxPurchase = min(maxPurchase, numAvailable * quantity) end
this.defaultStack = specialMax > 0 and specialMax <= maxPurchase and specialMax or quantity
if not name or maxPurchase == 0 then
return
elseif maxPurchase == 1 then
MerchantItemButton_OnClick("LeftButton", 1)
return
end
OpenBuyEmAllFrame(maxPurchase, "BOTTOMLEFT", "TOPLEFT")
end
-- Determines free bag space.
function BuyEmAll_FreeSpace(name, itemID)
local returns = { freeSpace = 0, specialSpace = 0}
for theBag = 0,4 do
local which = "freeSpace"
local doBag = true
if theBag > 0 then
local _,_,_,_,_,_,bagSubType =
GetItemInfoFromItemLink(GetInventoryItemLink("player", theBag + 19)) -- Bag #1 is in inventory slot 20
if bagSubType == "Ammo Pouch" and this.itemSubType == "Bullet" or
bagSubType == "Quiver" and this.itemSubType == "Arrow" then
which = "specialSpace"
elseif bagSubType == "Ammo Pouch" and this.itemSubType ~= "Bullet" or
bagSubType == "Quiver" and this.itemSubType ~= "Arrow" or
bagSubType == "Herb Bag" and not BuyEmAll_IsSpecial("Herb") or
bagSubType == "Enchanting Bag" and not BuyEmAll_IsSpecial("Enchant") then
doBag = false
end
end
if doBag then
local numSlot = GetContainerNumSlots(theBag);
for theSlot = 1, numSlot do
local itemLink = GetContainerItemLink(theBag, theSlot);
if not itemLink then
returns[which] = returns[which] + this.stackSize;
elseif string.find(itemLink, "%["..name.."%]") then
local _,itemCount = GetContainerItemInfo(theBag, theSlot)
returns[which] = returns[which] + this.stackSize - itemCount
end
end
end
end
return returns.freeSpace, returns.specialSpace
end
-- Determine whether an item is an herb or enchanting material
function BuyEmAll_IsSpecial(which)
for itemID in gfind(BuyEmAll_SpecialItems[which], "%d+") do
if tonumber(this.itemID) == tonumber(itemID) then return true end
end
return false
end
function BuyEmAll_SplitStack(amount)
local button = BuyEmAllFrame.owner
if (amount > 0) then
amount = ceil(amount/button.presetStack) * button.presetStack
if amount > button.stackSize and amount > button.defaultStack then
local dialog = StaticPopup_Show("BUYEMALL_CONFIRM", amount, button.itemName)
dialog.data = amount
elseif button.presetStack > 1 then
BuyEmAll_OnAccept(amount)
else
BuyMerchantItem(button:GetID(), amount);
BuyEmAllFrame:Hide()
end
end
end
function BuyEmAll_OnAccept(amount)
BuyEmAllFrame:Hide()
local button = BuyEmAllFrame.owner
local numLoops, purchAmount, leftover
if button.presetStack > 1 then
numLoops = amount/button.presetStack
purchAmount = 1
leftover = 0
else
numLoops = floor(amount/button.stackSize)
purchAmount = button.stackSize
leftover = mod(amount, button.stackSize)
end
for i = 1, numLoops do
BuyMerchantItem(button:GetID(), purchAmount)
end
if leftover > 0 then BuyMerchantItem(button:GetID(), leftover) end
end
local OldMerchantFrame_OnHide = MerchantFrame_OnHide
function MerchantFrame_OnHide(...)
StaticPopup_Hide("BUYEMALL_CONFIRM")
return OldMerchantFrame_OnHide(unpack(arg))
end
function BuyEmAll_UpdateCost(amount)
local button = BuyEmAllFrame.owner
local purchase = ceil((amount and amount or BuyEmAllFrame.split) / button.presetStack)
local cost = purchase * button.price
MoneyFrame_Update("BuyEmAllCostMoney", cost)
end
function BuyEmAllStack_Click()
BuyEmAll_ConfirmPurchase(BuyEmAllFrame.owner.stackSize)
end
function BuyEmAllMax_Click()
BuyEmAll_ConfirmPurchase(BuyEmAllFrame.maxStack)
end
function BuyEmAll_ConfirmPurchase(amount)
local dialog = StaticPopup_Show("BUYEMALL_CONFIRM", amount, BuyEmAllFrame.owner.itemName)
dialog.data = amount
end
function BuyEmAllStackButton_Enter()
local amount = BuyEmAllFrame.owner.stackSize
BuyEmAll_UpdateCost(amount)
GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT")
GameTooltip:SetText(BUYEMALL_STACK_SIZE.." - |cFFFFFFFF"..amount.."|r")
end
function BuyEmAllMaxButton_Enter()
local amount = BuyEmAllFrame.maxStack
BuyEmAll_UpdateCost(amount)
GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT")
GameTooltip:SetText(BUYEMALL_CAN_BUY.." - |cFFFFFFFF"..amount.."|r")
GameTooltip:AddDoubleLine(BUYEMALL_CAN_FIT, BuyEmAllFrame.owner.bagMax,1,1,1,1,1,1)
GameTooltip:AddDoubleLine(BUYEMALL_CAN_AFFORD, BuyEmAllFrame.owner.moneyMax,1,1,1,1,1,1)
local available = BuyEmAllFrame.owner.available
if available == -1 then
available = "∞"
end
GameTooltip:AddDoubleLine(BUYEMALL_AVAILABLE, available,1,1,1,1,1,1)
GameTooltip:Show()
end
function BuyEmAllMSButton_Leave()
BuyEmAll_UpdateCost()
GameTooltip:Hide()
end
--[[ Below is the modified code from the built-in StackSplitFrame ]]
function OpenBuyEmAllFrame(maxStack, anchor, anchorTo)
if ( BuyEmAllFrame.owner ) then
BuyEmAllFrame.owner.hasBuyEmAll = 0;
end
BuyEmAllFrame.maxStack = maxStack;
if ( BuyEmAllFrame.maxStack < 2 ) then
BuyEmAllFrame:Hide();
return;
end
BuyEmAllFrame.owner = this;
this.hasBuyEmAll = 1;
BuyEmAllFrame.split = this.defaultStack;
BuyEmAllFrame.typing = 0;
BuyEmAllText:SetText(BuyEmAllFrame.split);
BuyEmAllLeftButton:Disable();
BuyEmAllRightButton:Enable();
BuyEmAllStackButton:SetText(BuyEmAllStackButton.defaultText)
BuyEmAllMaxButton:SetText(BuyEmAllMaxButton.defaultText)
BuyEmAll_UpdateCost()
BuyEmAllStackButton:Enable()
if BuyEmAllFrame.maxStack < this.stackSize then
BuyEmAllStackButton:Disable()
end
BuyEmAllFrame:ClearAllPoints();
BuyEmAllFrame:SetPoint(anchor, this, anchorTo, 0, 0);
BuyEmAllFrame:Show();
end
function BuyEmAllFrame_OnChar()
if ( arg1 < "0" or arg1 > "9" ) then
return;
end
if ( this.typing == 0 ) then
this.typing = 1;
this.split = 0;
end
local split = (this.split * 10) + arg1;
if ( split == this.split ) then
if( this.split == 0 ) then
this.split = 1;
end
BuyEmAll_UpdateCost()
return;
end
if ( split <= this.maxStack ) then
this.split = split;
BuyEmAllText:SetText(split);
if ( split == this.maxStack ) then
BuyEmAllRightButton:Disable();
else
BuyEmAllRightButton:Enable();
end
if ( split <= this.owner.presetStack ) then
BuyEmAllLeftButton:Disable();
else
BuyEmAllLeftButton:Enable();
end
elseif ( split == 0 ) then
this.split = 1;
end
BuyEmAll_UpdateCost()
end
function BuyEmAllFrame_OnKeyDown()
if ( arg1 == "BACKSPACE" or arg1 == "DELETE" ) then
if ( this.typing == 0 or this.split == 1 ) then
return;
end
this.split = floor(this.split / 10);
if ( this.split <= 1 ) then
this.split = 1;
this.typing = 0;
end
if ( this.split <= this.owner.presetStack ) then
BuyEmAllLeftButton:Disable();
else
BuyEmAllLeftButton:Enable();
end
BuyEmAllText:SetText(this.split);
if ( this.money == this.maxStack ) then
BuyEmAllRightButton:Disable();
else
BuyEmAllRightButton:Enable();
end
BuyEmAll_UpdateCost()
elseif ( arg1 == "ENTER" ) then
BuyEmAllOkay_Click();
elseif ( arg1 == "ESCAPE" ) then
BuyEmAllCancel_Click();
elseif ( arg1 == "LEFT" or arg1 == "DOWN" ) then
BuyEmAllLeft_Click();
elseif ( arg1 == "RIGHT" or arg1 == "UP" ) then
BuyEmAllRight_Click();
end
end
function BuyEmAllLeft_Click()
local preset = BuyEmAllFrame.owner.presetStack
if ( BuyEmAllFrame.split <= preset ) then
return;
end
local decrease = mod(BuyEmAllFrame.split, preset)
decrease = decrease == 0 and preset or decrease
BuyEmAllFrame.split = BuyEmAllFrame.split - decrease
BuyEmAllText:SetText(BuyEmAllFrame.split)
if ( BuyEmAllFrame.split <= preset ) then
BuyEmAllLeftButton:Disable()
end
BuyEmAllRightButton:Enable()
BuyEmAll_UpdateCost()
end
function BuyEmAllRight_Click()
local preset = BuyEmAllFrame.owner.presetStack
local increase = preset - mod(BuyEmAllFrame.split, preset)
if ( BuyEmAllFrame.split + increase > BuyEmAllFrame.maxStack ) then
return;
end
BuyEmAllFrame.split = BuyEmAllFrame.split + increase;
BuyEmAllText:SetText(BuyEmAllFrame.split);
if ( BuyEmAllFrame.split == BuyEmAllFrame.maxStack ) then
BuyEmAllRightButton:Disable();
end
BuyEmAllLeftButton:Enable();
BuyEmAll_UpdateCost()
end
function BuyEmAllOkay_Click()
if ( BuyEmAllFrame.owner ) then
BuyEmAllFrame.owner.SplitStack(BuyEmAllFrame.split);
end
end
function BuyEmAllCancel_Click()
BuyEmAllFrame:Hide()
StaticPopup_Hide("BUYEMALL_CONFIRM")
end
function BuyEmAllFrame_OnHide()
if ( this.owner ) then
BuyEmAllFrame.owner.hasBuyEmAll = 0;
end
StaticPopup_Hide("BUYEMALL_CONFIRM")
end