vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- BuyEmAll - By Cogwheel v1.12 - See readme.txt
2  
3 --[[Hook BuyMerchantItem for debugging purposes
4 function BuyMerchantItem(button, amount)
5 if not amount then amount = 1 end
6 print("Buying "..amount.." items.")
7 end --]]
8  
9 -- Herb & Enchanting item lists courtesy of Periodic Table by Tekkub
10 BuyEmAll_SpecialItems = {
11 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",
12 Enchant = "11083 16204 11137 11176 10940 11174 10938 11135 11175 16202 11134 16203 10998 11082 10939 11084 14343 11139 10978 11177 14344 11138 11178",
13 }
14  
15  
16  
17  
18 function BuyEmAllFrame_OnLoad()
19 -- Set up confirmation dialog
20 StaticPopupDialogs["BUYEMALL_CONFIRM"] = {
21 text = BUYEMALL_CONFIRMATION,
22 button1 = TEXT(YES),
23 button2 = TEXT(NO),
24 OnAccept = BuyEmAll_OnAccept,
25 timeout = 0,
26 hideOnEscape = true,
27 }
28  
29 BuyEmAllStackButton.defaultText = BUYEMALL_STACK
30 BuyEmAllMaxButton.defaultText = BUYEMALL_MAX
31  
32  
33 -- Replace the SplitStack callback and for each merchant item button
34 for i=1,12 do
35 local button=getglobal("MerchantItem"..i.."ItemButton")
36 button.SplitStack = BuyEmAll_SplitStack
37 button:SetScript("OnHide", function()
38 if ( this.hasBuyEmAll == 1 ) then
39 BuyEmAllFrame:Hide();
40 end
41 end)
42 end
43 end
44  
45  
46  
47  
48 function BuyEmAllCostMoney_OnLoad()
49 MoneyTypeInfo["BUYEMALL"] = {
50 UpdateFunc = function() return this.staticMoney end,
51 showSmallerCoins = "Backpack",
52 fixedWidth = 1,
53 collapse = 0,
54 truncateSmallCoins = nil
55 }
56 this.small = 1
57 this.staticMoney = 0
58 MoneyFrame_SetType("BUYEMALL")
59 end
60  
61  
62  
63  
64 --[[ Since I have to control two different paths through this function, I just
65 recreated it here to make life a bit easier. ]]
66 function MerchantItemButton_OnClick(button, ignoreModifiers)
67 if ( MerchantFrame.selectedTab == 1 ) then
68 -- Is merchant frame
69 if ( button == "LeftButton" ) then
70 if ( IsControlKeyDown() and not ignoreModifiers ) then
71 DressUpItemLink(GetMerchantItemLink(this:GetID()));
72 elseif ( IsShiftKeyDown() and not ignoreModifiers ) then
73 if ( ChatFrameEditBox:IsVisible() ) then
74 ChatFrameEditBox:Insert(GetMerchantItemLink(this:GetID()));
75 else
76 BuyEmAll_ChooseAmount()
77 end
78 else
79 PickupMerchantItem(this:GetID());
80 end
81 else
82 if ( IsControlKeyDown() and not ignoreModifiers ) then
83 return;
84 elseif ( IsShiftKeyDown() and not ignoreModifiers ) then
85 BuyEmAll_ChooseAmount()
86 else
87 BuyMerchantItem(this:GetID());
88 end
89 end
90 else
91 -- Is buyback item
92 BuybackItem(this:GetID());
93 end
94 end
95  
96  
97  
98  
99 -- Courtesy of wowwiki.com
100 function GetItemInfoFromItemLink(link)
101 local itemId = nil;
102 if ( type(link) == "string" ) then
103 _,_, itemId = string.find(link, "item:(%d+):");
104 end
105 if ( itemId ) then
106 return itemId, GetItemInfo(itemId);
107 end
108 end
109  
110  
111  
112  
113 -- Figures out maximum purchase amount and shows the BuyEmAllFrame
114 function BuyEmAll_ChooseAmount()
115 local name, _, price, quantity, numAvailable = GetMerchantItemInfo(this:GetID());
116 this.presetStack = quantity
117 this.price = price
118 this.itemName = name
119 this.itemID, _,_,_,_,_, this.itemSubType, this.stackSize =
120 GetItemInfoFromItemLink(GetMerchantItemLink(this:GetID()))
121  
122 local bagSpace, specialSpace = BuyEmAll_FreeSpace(name, itemID)
123 local specialMax = floor(specialSpace / quantity) * quantity
124 this.bagMax = floor(bagSpace / quantity) * quantity + specialMax
125 this.moneyMax = floor(GetMoney() / price) * quantity
126 this.available = numAvailable
127 local maxPurchase = min(this.bagMax, this.moneyMax)
128 if numAvailable ~= -1 then maxPurchase = min(maxPurchase, numAvailable * quantity) end
129 this.defaultStack = specialMax > 0 and specialMax <= maxPurchase and specialMax or quantity
130  
131 if not name or maxPurchase == 0 then
132 return
133 elseif maxPurchase == 1 then
134 MerchantItemButton_OnClick("LeftButton", 1)
135 return
136 end
137  
138 OpenBuyEmAllFrame(maxPurchase, "BOTTOMLEFT", "TOPLEFT")
139 end
140  
141  
142  
143  
144 -- Determines free bag space.
145 function BuyEmAll_FreeSpace(name, itemID)
146 local returns = { freeSpace = 0, specialSpace = 0}
147  
148 for theBag = 0,4 do
149 local which = "freeSpace"
150 local doBag = true
151  
152 if theBag > 0 then
153 local _,_,_,_,_,_,bagSubType =
154 GetItemInfoFromItemLink(GetInventoryItemLink("player", theBag + 19)) -- Bag #1 is in inventory slot 20
155 if bagSubType == "Ammo Pouch" and this.itemSubType == "Bullet" or
156 bagSubType == "Quiver" and this.itemSubType == "Arrow" then
157 which = "specialSpace"
158 elseif bagSubType == "Ammo Pouch" and this.itemSubType ~= "Bullet" or
159 bagSubType == "Quiver" and this.itemSubType ~= "Arrow" or
160 bagSubType == "Herb Bag" and not BuyEmAll_IsSpecial("Herb") or
161 bagSubType == "Enchanting Bag" and not BuyEmAll_IsSpecial("Enchant") then
162 doBag = false
163 end
164 end
165  
166 if doBag then
167 local numSlot = GetContainerNumSlots(theBag);
168 for theSlot = 1, numSlot do
169 local itemLink = GetContainerItemLink(theBag, theSlot);
170 if not itemLink then
171 returns[which] = returns[which] + this.stackSize;
172 elseif string.find(itemLink, "%["..name.."%]") then
173 local _,itemCount = GetContainerItemInfo(theBag, theSlot)
174 returns[which] = returns[which] + this.stackSize - itemCount
175 end
176 end
177 end
178 end
179 return returns.freeSpace, returns.specialSpace
180 end
181  
182  
183  
184  
185 -- Determine whether an item is an herb or enchanting material
186 function BuyEmAll_IsSpecial(which)
187 for itemID in gfind(BuyEmAll_SpecialItems[which], "%d+") do
188 if tonumber(this.itemID) == tonumber(itemID) then return true end
189 end
190 return false
191 end
192  
193  
194  
195  
196 function BuyEmAll_SplitStack(amount)
197 local button = BuyEmAllFrame.owner
198 if (amount > 0) then
199 amount = ceil(amount/button.presetStack) * button.presetStack
200 if amount > button.stackSize and amount > button.defaultStack then
201 local dialog = StaticPopup_Show("BUYEMALL_CONFIRM", amount, button.itemName)
202 dialog.data = amount
203 elseif button.presetStack > 1 then
204 BuyEmAll_OnAccept(amount)
205 else
206 BuyMerchantItem(button:GetID(), amount);
207 BuyEmAllFrame:Hide()
208 end
209 end
210 end
211  
212  
213  
214  
215 function BuyEmAll_OnAccept(amount)
216 BuyEmAllFrame:Hide()
217  
218 local button = BuyEmAllFrame.owner
219 local numLoops, purchAmount, leftover
220  
221 if button.presetStack > 1 then
222 numLoops = amount/button.presetStack
223 purchAmount = 1
224 leftover = 0
225 else
226 numLoops = floor(amount/button.stackSize)
227 purchAmount = button.stackSize
228 leftover = mod(amount, button.stackSize)
229 end
230  
231 for i = 1, numLoops do
232 BuyMerchantItem(button:GetID(), purchAmount)
233 end
234  
235 if leftover > 0 then BuyMerchantItem(button:GetID(), leftover) end
236 end
237  
238  
239  
240  
241 local OldMerchantFrame_OnHide = MerchantFrame_OnHide
242 function MerchantFrame_OnHide(...)
243 StaticPopup_Hide("BUYEMALL_CONFIRM")
244 return OldMerchantFrame_OnHide(unpack(arg))
245 end
246  
247  
248  
249  
250  
251 function BuyEmAll_UpdateCost(amount)
252 local button = BuyEmAllFrame.owner
253 local purchase = ceil((amount and amount or BuyEmAllFrame.split) / button.presetStack)
254 local cost = purchase * button.price
255  
256 MoneyFrame_Update("BuyEmAllCostMoney", cost)
257 end
258  
259  
260  
261  
262 function BuyEmAllStack_Click()
263 BuyEmAll_ConfirmPurchase(BuyEmAllFrame.owner.stackSize)
264 end
265  
266  
267  
268  
269 function BuyEmAllMax_Click()
270 BuyEmAll_ConfirmPurchase(BuyEmAllFrame.maxStack)
271 end
272  
273  
274  
275  
276 function BuyEmAll_ConfirmPurchase(amount)
277 local dialog = StaticPopup_Show("BUYEMALL_CONFIRM", amount, BuyEmAllFrame.owner.itemName)
278 dialog.data = amount
279 end
280  
281  
282  
283  
284 function BuyEmAllStackButton_Enter()
285 local amount = BuyEmAllFrame.owner.stackSize
286 BuyEmAll_UpdateCost(amount)
287  
288 GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT")
289 GameTooltip:SetText(BUYEMALL_STACK_SIZE.." - |cFFFFFFFF"..amount.."|r")
290 end
291  
292  
293  
294  
295 function BuyEmAllMaxButton_Enter()
296 local amount = BuyEmAllFrame.maxStack
297 BuyEmAll_UpdateCost(amount)
298  
299 GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT")
300 GameTooltip:SetText(BUYEMALL_CAN_BUY.." - |cFFFFFFFF"..amount.."|r")
301 GameTooltip:AddDoubleLine(BUYEMALL_CAN_FIT, BuyEmAllFrame.owner.bagMax,1,1,1,1,1,1)
302 GameTooltip:AddDoubleLine(BUYEMALL_CAN_AFFORD, BuyEmAllFrame.owner.moneyMax,1,1,1,1,1,1)
303  
304 local available = BuyEmAllFrame.owner.available
305 if available == -1 then
306 available = "∞"
307 end
308 GameTooltip:AddDoubleLine(BUYEMALL_AVAILABLE, available,1,1,1,1,1,1)
309  
310 GameTooltip:Show()
311 end
312  
313  
314  
315  
316 function BuyEmAllMSButton_Leave()
317 BuyEmAll_UpdateCost()
318 GameTooltip:Hide()
319 end
320  
321  
322  
323  
324 --[[ Below is the modified code from the built-in StackSplitFrame ]]
325  
326  
327  
328 function OpenBuyEmAllFrame(maxStack, anchor, anchorTo)
329 if ( BuyEmAllFrame.owner ) then
330 BuyEmAllFrame.owner.hasBuyEmAll = 0;
331 end
332  
333 BuyEmAllFrame.maxStack = maxStack;
334 if ( BuyEmAllFrame.maxStack < 2 ) then
335 BuyEmAllFrame:Hide();
336 return;
337 end
338  
339 BuyEmAllFrame.owner = this;
340 this.hasBuyEmAll = 1;
341 BuyEmAllFrame.split = this.defaultStack;
342 BuyEmAllFrame.typing = 0;
343 BuyEmAllText:SetText(BuyEmAllFrame.split);
344 BuyEmAllLeftButton:Disable();
345 BuyEmAllRightButton:Enable();
346  
347 BuyEmAllStackButton:SetText(BuyEmAllStackButton.defaultText)
348 BuyEmAllMaxButton:SetText(BuyEmAllMaxButton.defaultText)
349 BuyEmAll_UpdateCost()
350  
351 BuyEmAllStackButton:Enable()
352 if BuyEmAllFrame.maxStack < this.stackSize then
353 BuyEmAllStackButton:Disable()
354 end
355  
356 BuyEmAllFrame:ClearAllPoints();
357 BuyEmAllFrame:SetPoint(anchor, this, anchorTo, 0, 0);
358 BuyEmAllFrame:Show();
359 end
360  
361  
362  
363  
364 function BuyEmAllFrame_OnChar()
365 if ( arg1 < "0" or arg1 > "9" ) then
366 return;
367 end
368  
369 if ( this.typing == 0 ) then
370 this.typing = 1;
371 this.split = 0;
372 end
373  
374 local split = (this.split * 10) + arg1;
375 if ( split == this.split ) then
376 if( this.split == 0 ) then
377 this.split = 1;
378 end
379 BuyEmAll_UpdateCost()
380 return;
381 end
382  
383 if ( split <= this.maxStack ) then
384 this.split = split;
385 BuyEmAllText:SetText(split);
386 if ( split == this.maxStack ) then
387 BuyEmAllRightButton:Disable();
388 else
389 BuyEmAllRightButton:Enable();
390 end
391 if ( split <= this.owner.presetStack ) then
392 BuyEmAllLeftButton:Disable();
393 else
394 BuyEmAllLeftButton:Enable();
395 end
396 elseif ( split == 0 ) then
397 this.split = 1;
398 end
399 BuyEmAll_UpdateCost()
400 end
401  
402  
403  
404  
405 function BuyEmAllFrame_OnKeyDown()
406 if ( arg1 == "BACKSPACE" or arg1 == "DELETE" ) then
407 if ( this.typing == 0 or this.split == 1 ) then
408 return;
409 end
410  
411 this.split = floor(this.split / 10);
412 if ( this.split <= 1 ) then
413 this.split = 1;
414 this.typing = 0;
415 end
416 if ( this.split <= this.owner.presetStack ) then
417 BuyEmAllLeftButton:Disable();
418 else
419 BuyEmAllLeftButton:Enable();
420 end
421 BuyEmAllText:SetText(this.split);
422 if ( this.money == this.maxStack ) then
423 BuyEmAllRightButton:Disable();
424 else
425 BuyEmAllRightButton:Enable();
426 end
427 BuyEmAll_UpdateCost()
428 elseif ( arg1 == "ENTER" ) then
429 BuyEmAllOkay_Click();
430 elseif ( arg1 == "ESCAPE" ) then
431 BuyEmAllCancel_Click();
432 elseif ( arg1 == "LEFT" or arg1 == "DOWN" ) then
433 BuyEmAllLeft_Click();
434 elseif ( arg1 == "RIGHT" or arg1 == "UP" ) then
435 BuyEmAllRight_Click();
436 end
437 end
438  
439  
440  
441  
442 function BuyEmAllLeft_Click()
443 local preset = BuyEmAllFrame.owner.presetStack
444 if ( BuyEmAllFrame.split <= preset ) then
445 return;
446 end
447  
448 local decrease = mod(BuyEmAllFrame.split, preset)
449 decrease = decrease == 0 and preset or decrease
450  
451 BuyEmAllFrame.split = BuyEmAllFrame.split - decrease
452  
453 BuyEmAllText:SetText(BuyEmAllFrame.split)
454 if ( BuyEmAllFrame.split <= preset ) then
455 BuyEmAllLeftButton:Disable()
456 end
457 BuyEmAllRightButton:Enable()
458 BuyEmAll_UpdateCost()
459 end
460  
461  
462  
463  
464 function BuyEmAllRight_Click()
465 local preset = BuyEmAllFrame.owner.presetStack
466 local increase = preset - mod(BuyEmAllFrame.split, preset)
467  
468 if ( BuyEmAllFrame.split + increase > BuyEmAllFrame.maxStack ) then
469 return;
470 end
471  
472 BuyEmAllFrame.split = BuyEmAllFrame.split + increase;
473 BuyEmAllText:SetText(BuyEmAllFrame.split);
474 if ( BuyEmAllFrame.split == BuyEmAllFrame.maxStack ) then
475 BuyEmAllRightButton:Disable();
476 end
477 BuyEmAllLeftButton:Enable();
478 BuyEmAll_UpdateCost()
479 end
480  
481  
482  
483  
484 function BuyEmAllOkay_Click()
485 if ( BuyEmAllFrame.owner ) then
486 BuyEmAllFrame.owner.SplitStack(BuyEmAllFrame.split);
487 end
488 end
489  
490  
491  
492  
493 function BuyEmAllCancel_Click()
494 BuyEmAllFrame:Hide()
495 StaticPopup_Hide("BUYEMALL_CONFIRM")
496 end
497  
498  
499  
500  
501 function BuyEmAllFrame_OnHide()
502 if ( this.owner ) then
503 BuyEmAllFrame.owner.hasBuyEmAll = 0;
504 end
505 StaticPopup_Hide("BUYEMALL_CONFIRM")
506 end