WoWInterface SVN BuyDropper

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 9 to Rev 10
    Reverse comparison

Rev 9 → Rev 10

tags/0.9B5/BuyDropperQueue.lua New file
0,0 → 1,83
BUYDROPPER_PURCHASE_DELAY = 0.5
 
function BuyDropper:InitPurchaseQueue()
self.queue = {}
end
 
 
 
 
function BuyDropper:QueuePurchase(index, priority)
local item = self.list[priority]
if not item.index then -- Items with indexes have already been added to the list
item.priority = priority
item.index = index
tinsert(self.queue, item)
end
end
 
 
 
 
function BuyDropper:ClearPurchaseQueue()
for i = 1, #self.queue do
local item = tremove(self.queue)
item.index = nil
item.priority = nil
end
self:CleanupPurchaseQueue()
end
 
 
 
 
function BuyDropper:CleanupPurchaseQueue()
self.hasWaited = nil
self:CancelScheduledEvent("BUYDROPPER_MERCHANT_WAIT")
self:CancelScheduledEvent("BUYDROPPER_DO_PURCHASES")
end
 
 
 
 
function BuyDropper:ReleasePurchaseQueue()
sort(self.queue, function(item1, item2)
return item1.priority < item2.priority
end)
 
self:ScheduleRepeatingEvent("BUYDROPPER_DO_PURCHASES", function()
self:PurchaseNextQueued()
end, BUYDROPPER_PURCHASE_DELAY)
end
 
 
 
 
function BuyDropper:PurchaseNextQueued()
if self.hasWaited then
self.hasPurchased = true
local item = tremove(self.queue, 1)
if item then
local didPurchase = self:PurchaseItem(item)
item.index = nil
item.priority = nil
if not didPurchase then
self:ClearPurchaseQueue()
end
else
self:CleanupPurchaseQueue()
end
end
end
 
 
 
 
function BuyDropper:GetQueueCost()
local cost = 0
for i, item in ipairs(self.queue) do
local num = self:NumToBuy(item)
cost = cost + (num * item.price)
end
return cost
end
tags/0.9B5/readme.html New file
0,0 → 1,339
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>BuyDropper Readme</title>
<style type="text/css">
h2,h3 { border-bottom: 1px solid; }
a:visited:after { content: " ✓"; }
 
p.notice {
font-size: smaller;
color: #999;
}
 
ol.footnotes {
font-size: small;
}
 
.item {
font-size: small;
font-family: Arial, Helvetica, sans-serif;
 
border: solid 1px;
border-top-color: #FFF;
border-left-color: #888;
border-right-color: #888;
border-bottom-color: #555;
 
-moz-border-radius: 4px;
 
background-color: #000;
color: #FFF;
padding: 2px;
}
.poor { color: gray; }
.common { color: white; }
.uncommon { color: #1EFF00; }
.rare { color: #0080FF; }
.epic { color: #B048F8; }
.legendary { color: #F07902; }
.artifact { color: #FFCF00; }
.captionedImage {
float: right;
font-size: small;
font-family: Arial, Helvetica, sans-serif;
 
border: solid 1px;
border-top-color: #FFF;
border-left-color: #888;
border-right-color: #888;
border-bottom-color: #555;
 
-moz-border-radius: 4px;
 
background-color: #000;
color: #FFF;
padding: 2px;
}
.captionedImage div {
text-align: center;
}
 
 
@media screen {
body {
font-family: "Trebuchet MS", Helvetica, Verdana, Arial, sans-serif;
color: #FFF;
background: #333;
width: 80%;
min-width: 600px;
padding-left: 30px;
}
h1,h2,h3,h4,h5,h6 {
font-family: Georgia, "Times New Roman", Times, serif;
color: #ED0;
}
h1,h2,h3,h5,h6 {
font-family: Georgia, "Times New Roman", Times, serif;
}
h2,h3 { border-bottom-color: #ED0; }
p,h3,h4,h5,h6 { margin-left: 30px; }
a:link {
color: #FC0;
text-decoration: none;
}
a:visited {
color: #999;
text-decoration: none;
}
a:hover {
color: #0F0;
}
a:active {
color: #0F0;
}
.gold { color: #ED0; }
.silver { color: #BBB; }
.copper { color: #D63; }
}
 
@media print {
body {
font-family: "Times New Roman", Times, serif;
}
h1,h2,h3,h4,h5,h6 {
font-family: Arial, Helvetica, sans-serif;
}
}
</style>
</head>
 
<body>
<h1>BuyDropper</h1>
<p>By Cogwheel — v0.9B4<br />
Inspired by FreeRefills by Kyahx </p>
<p>BuyDropper keeps a list of items to purchase automatically from vendors.</p>
<p>Please visit <a href="http://cogwheel.wowinterface.com">Cogwheel’s Workshop</a> for updates, bug reports, feature requests, etc. </p>
<p class="notice">THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. </p>
<ul>
<li><a href="#guide">Guide</a>
<ul>
<li><a href="#managing">Managing your list
</a>
<ul>
<li><a href="#adding">Adding items </a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#reference">Reference</a>
<ul>
<li><a href="#options">options</a></li>
<li><a href="#add">add</a></li>
<li><a href="#list">list</a></li>
<li><a href="#change">change</a></li>
<li><a href="#priority">priority</a></li>
<li><a href="#remove">remove</a></li>
<li><a href="#clear">clear</a> </li>
<li><a href="#vendor">vendor</a>
<ul>
<li><a href="#vendortoggle">toggle</a></li>
<li><a href="#confirm">confirm</a></li>
<li><a href="#budget">budget</a></li>
<li><a href="#fallthrough">fallthrough</a></li>
</ul>
</li>
<li><a href="#bank">bank</a></li>
<li><a href="#overstock">overstock</a></li>
<li><a href="#dropper">dropper</a>
<ul>
<li><a href="#droppertoggle">toggle</a></li>
<li><a href="#position">position</a></li>
<li><a href="#label">label</a></li>
</ul>
</li>
<li><a href="#profile">profile</a></li>
<li><a href="#standby">standby</a></li>
<li><a href="#about">about</a></li>
</ul>
</li>
<li><a href="#bugs">Bugs/Improvements</a></li>
<li><a href="#changes">Changes</a></li>
</ul>
<h2><a name="guide" id="guide"></a>Guide</h2>
<h3><a name="managing" id="managing"></a>Managing your list</h3>
<h4><a name="adding" id="adding"></a>Adding items </h4>
<div class="captionedImage"><img src="images/dropper.jpg" alt="Picture of Dropper" width="156" height="138" />
<div>Dropper</div></div>
<p>The first thing you’ll want to do is add an item to BuyDropper’s tracking list. This can be done in two easy ways. By default, every vendor window has a dropper in the upper right and there is also a dropper on BuyDropper’s options window. Simply drag and drop an item onto one of these droppers and a window will appear where you can enter the amount you want to track. When you click Accept or press Enter, BuyDropper will print a message showing the item and quantity added to the list.</p>
<p>The other way to add items is the /buydropper add command. This duality of GUI/slash commands is seen throughout BuyDropper’s operations. For the rest of the guide, I will focus on the GUI aspects. You can use the Reference below to discover how to use the various commands.</p>
<p style="color: #F00">[TODO: Rest of the documentation. For now, take a look at /buydropper options and the Reference below] </p>
<h2><a name="reference" id="reference"></a>Reference</h2>
<p>These are all the slash commands available from BuyDropper. Typing /buydropper (or /bd) will show this list of commands. Sub-commands are displayed when you enter the main command with no options. E.g. /buydropper vendor will display all the sub-commands of vendor. </p>
<h3><a name="options" id="options"></a>options</h3>
<p>Usage: /buydropper options</p>
<p>Opens the BuyDropper options window. The options window provides support for most of the operations of the following slash commands. Any that are unique to the slash commands will be so noted.</p>
<h3><a name="add" id="add"></a>add</h3>
<p>Usage: /buydropper add &lt;item link&gt; &lt;amount&gt;</p>
<p>Adds an item to the bottom of your tracking list or changes the amount of an item you are already tracking. </p>
<p>To use this command, type <kbd>/buydropper add</kbd> with a space after it. Now shift-click any item at a vendor, in your backpack, on your character, etc. Add another space, and type in the amount of the item you want to track. </p>
<h3><a name="list" id="list"></a>list - slash command only (for now) </h3>
<p>Usage: /buydropper list</p>
<p>Lists the items you are currently tracking in order of descending priority.</p>
<h3><a name="change" id="change"></a>change - slash command only (for now)</h3>
<p>Usage: /buydropper change &lt;priority&gt; &lt;amount&gt;</p>
<p>Changes the tracking amount for the given item. priority is obtained from the list command. amount must be 1 or more. </p>
<h3><a name="priority" id="priority"></a>priority - slash command only (for now) </h3>
<p>Usage: /buydropper priority &lt;current priority&gt; &lt;new priority&gt;</p>
<p>Changes the priority of an item in your tracking list. current priority is obtained from the <a href="#list">list</a> command. new priority must be a number from 1 to the number of items you are tracking. The item’s entry is removed from its current location and inserted at the new priority, shifting the item currently at that priority down the list.</p>
<h3><a name="remove" id="remove"></a>remove - slash command only (for now) </h3>
<p>Usage: /buydropper remove &lt;priority&gt;</p>
<p>Removes the item at the specified priority from your tracking list.</p>
<h3><a name="clear" id="clear"></a>clear</h3>
<p>Usage: /buydropper clear</p>
<p>Clears all items from your list. A confirmation will appear to make sure you mean it. </p>
<h3><a name="vendor" id="vendor"></a>vendor</h3>
<p>Usage: /buydropper vendor &lt;sub-command&gt;</p>
<p>Sub-commands:</p>
<h4><a name="vendortoggle" id="vendortoggle"></a>toggle</h4>
<p>Usage: /buydropper vendor toggle<br />
Default: enabled </p>
<p>Toggles whether vendors should be scanned for items you are tracking.</p>
<h4><a name="confirm" id="confirm"></a>confirm </h4>
<p>Usage: /buydropper vendor confirm <br />
Default: enabled </p>
<p>Toggles whether to confirm purchases from vendors.</p>
<h4><a name="budget" id="budget"></a>budget - slash command only (for now) </h4>
<p>Usage: /buydropper vendor budget &lt;number&gt;<br />
Default: 50 </p>
<p>Sets your budget for automatic purchases from vendors. number must be from 1 to 100 and represents the percentage of your total money BuyDropper is allowed to use when purchasing a given item at a vendor. This is only applicable if the confirmation is turned off. </p>
<h4><a name="fallthrough" id="fallthrough"></a>fallthrough - slash command only (for now) </h4>
<p>Usage: /buydropper vendor fallthrough<br />
Default: disabled </p>
<p>Toggles whether to continue purchasing lower-priority items when higher-priority items cannot be purchased for lack of space or money. </p>
<h3><a name="bank" id="bank"></a>bank</h3>
<p>Usage: /buydropper bank<br />
Default: enabled </p>
<p>Toggles whether to withdraw items from the bank. Note: bank withdrawals are not yet implemented. </p>
<h3><a name="overstock" id="overstock"></a>overstock</h3>
<p>Usage: /buydropper overstock<br />
Default: disabled </p>
<p>Toggles whether to overstock items that come in preset stacks like food or water. For example, say you are tracking <span class="item common">Ice Cold Milk</span> × 20 and you have 17 in your inventory and you open a vendor who sells <span class="item common">Ice Cold Milk</span>. With overstock enabled, you will buy a bundle of 5 to bring your total to 22.</p>
<h3><a name="dropper" id="dropper"></a>dropper</h3>
<p>Usage: /buydropper dropper &lt;sub-command&gt;</p>
<p>Sub-commands:</p>
<h4><a name="droppertoggle" id="droppertoggle"></a>toggle</h4>
<p>Usage: /buydropper dropper toggle<br />
Default: enabled
</p>
<p>Toggles whether to show the dropper in vendor windows. </p>
<h4><a name="position" id="position"></a>position</h4>
<p>Usage: /buydropper dropper position &lt;number&gt;<br />
Default: 100 </p>
<p>Sets the position of the dropper in vendor windows. number must be from 1 to 100 and represents the percentage from 0 in the far left to 100 in the far right. </p>
<h4><a name="label" id="label"></a>label </h4>
<p>Usage: /buydropper dropper label<br />
Default: enabled</p>
<p>Toggles whether to show the label next to the dropper in vendor windows. </p>
<h3><a name="profile" id="profile"></a>profile - slash command only </h3>
<p>Usage: /buydropper profile &lt;sub-command&gt;</p>
<p>Sub-commands:</p>
<h4><a name="choose" id="choose"></a>choose</h4>
<p>Usage: /buydropper profile choose &lt;name or shortcut&gt;<br />
Default: Character: &lt;name&gt; of &lt;realm&gt;</p>
<p>Chooses a pre-existing profile to use for BuyDropper’s settings. This is stored per-character so every character can use a particular profile. Using this command without providing a profile parameter will display a list of possible profiles to use. If you want to create a new profile, use the other sub-command.</p>
<p>You can provide either the full name of the profile, e.g. Character: Cogwheel of Shadowsong or a shortcut. Possible shortcuts are char, realm, or class.</p>
<h4><a name="other" id="other"></a>other</h4>
<p>Usage: /buydropper profile other &lt;name or shortcut&gt;<br />
Default: char</p>
<p>Similar to the choose sub-command, but creates a profile if the name you specify does not exist.</p>
<h4><a name="copy" id="copy"></a>copy</h4>
<p>Usage: /buydropper profile copy &lt;name or shortcut&gt;</p>
<p>Copies the data from another profile into your currently active profile. Running this command without providing a profile will display a list of profiles from which you can choose.</p>
<h3><a name="standby" id="standby"></a>standby - slash command only (for now)</h3>
<p>Usage: /buydropper standby<br />
Default: enabled</p>
<p>Turns BuyDropper on and off. When disabled, it will not do anything when you open a vendor or visit the bank.</p>
<h3><a name="about" id="about"></a>about - slash command only</h3>
<p>Usage: /buydropper about </p>
<p>Displays some basic information about BuyDropper. </p>
<h2><a name="bugs" id="bugs"></a>Bugs/Improvements</h2>
<ul>
<li>The GUI is not complete:
<ul>
<li> It does not support the Budget or Fallthrough vendor options.</li>
<li>The tracking list is not functional (hence none of the tracking list controls are either).</li>
</ul>
</li>
<li>BuyDropper does not yet withdraw items from the bank</li>
</ul>
<p>Please visit <a href="http://cogwheel.wowinterface.com">Cogwheel’s Workshop</a> if you have any suggestions or bug reports, and to see what is in store for the future.</p>
<h2><a name="changes" id="changes"></a>Changes</h2>
<h4>v0.9B4</h4>
<ul>
<li>When you add an item to the tracking list while at a vendor, it will be immediately purchased (or confirmed to be purchased). </li>
<li>You can now remove the last item in the tracking list. </li>
<li>Limited quantity items are now handled appropriately.</li>
</ul>
<h4>v0.9B3</h4>
<ul>
<li>Updated for 3.0.2.</li>
</ul>
<h4>v0.9B2-2.3</h4>
<ul>
<li>Updated Ace libraries. You no longer need other Ace mods to use this. </li>
</ul>
<h4>v0.9B2</h4>
<ul>
<li>Fixed a bug where an error would occur when buying items if you do not have BuyEmAll installed.</li>
</ul>
<h4>v0.9B1</h4>
<ul>
<li>Purchasing is now enabled.</li>
<li>Enabling BuyDropper while at a vendor will now scan the vendor.</li>
<li>Uses the new GetCursorInfo API instead of hooking all the Pickup_____Item functions (PickupMerchantItem is still hooked because GetCursorInfo doesn’t returns nil for merchant items).</li>
<li>Fixed the bug where if an error occurs while buying an item it will no longer attempt to buy that item when you open the vendor again.</li>
<li>Added /buydropper change command. </li>
<li>Budget will now only affect purchases if the confirmation is turned off. </li>
<li>Implemented the Clear List button in the options window.</li>
<li>/buydropper clear no longer requires the “yes” parameter. Instead it shows a confirmation dialog like the Clear List button in the options window.</li>
<li>Fixed a validation bug for the /buydropper priority command.</li>
</ul>
<h4><a name="09A4" id="09A4"></a>v0.9A4</h4>
<ul>
<li>Added purchasing code. You must un comment the section starting on line 275 of BuyDropperEngine.lua in order to enable this functionality. </li>
<li>No longer re scans a vendor from which you’ve already purchased an item until your next visit.</li>
<li>Added this readme</li>
</ul>
<h4>v0.9A3</h4>
<ul>
<li>Updated for 2.0.3.</li>
</ul>
<h4>v0.9A2</h4>
<ul>
<li>Fixed bug with CogsBagSpace.</li>
</ul>
<h4>v0.9A1</h4>
<ul>
<li>No longer requires FreeRefills.</li>
<li>Added all slash commands and the GUI options window.</li>
</ul>
<h4>v0.3</h4>
<ul>
<li>Added commands to customize the vendor dropper.</li>
<li>Updated Ace2 libraries.</li>
</ul>
<h4>v0.2</h4>
<ul>
<li>Entering 0 for the amount now removes the item from the list.</li>
<li>Added tracking buttons.</li>
</ul>
<h4>v0.1</h4>
<ul>
<li>Initial Release.</li>
</ul>
</body>
</html>
tags/0.9B5/BuyDropperEngine.lua New file
0,0 → 1,321
BUYDROPPER_MERCHANT_DELAY = 1
 
--[[
Tracking List Methods
]]
 
function BuyDropper:AddTrackingItem(link, amount)
local item = self:GetLinkItem(link)
if not item then
item = { id = self:ExtractItemID(link) }
tinsert(self.list, item)
self.idPriorityCache[item.id] = #self.list
end
 
item.amount = amount
self:UpdateDisplays()
if MerchantFrame:IsVisible() then
--for index, item in self:IterateTrackedMerchantItems() do
-- self:UpdatePrice(index, item)
--end
self:ScanMerchant()
end
self:Print("Added %s × %d", link, amount)
end
 
 
 
 
function BuyDropper:ChangeTrackingItem(priority, amount)
local item = self.list[priority]
local old = item.amount
item.amount = amount
self:UpdateDisplays()
self:Print("Changed tracking amount of %s from %d to %d", self:MakeItemLink(item.id), old, amount)
end
 
 
 
 
function BuyDropper:RemoveTrackingItem(priority)
local item = self:_RemoveTrackingItem(priority)
if priority <= #self.list then
self:UpdatePriorityCache()
end
self:UpdateDisplays()
self:Print("Removed %s from tracking list", self:MakeItemLink(item.id))
end
 
 
 
 
function BuyDropper:ClearTrackingList()
for i = #self.list, 1, -1 do
self:_RemoveTrackingItem(priority)
end
self:UpdateDisplays()
self:Print("Tracking list cleared")
end
 
 
 
 
function BuyDropper:_RemoveTrackingItem(priority)
local item = tremove(self.list, priority)
self.idPriorityCache[item.id] = nil
return item
end
 
 
 
 
function BuyDropper:SetTrackingPriority(current, new)
tinsert(self.list, new, tremove(self.list, current))
self:UpdatePriorityCache()
self:UpdateDisplays()
self:Print("Changed priority on %s from %d to %d", self:MakeItemLink(self.list[new].id), current, new)
end
 
 
 
 
function BuyDropper:GetLinkItem(link)
local id = self:ExtractItemID(link)
local priority = self.idPriorityCache[id]
return self.list[priority], priority
end
 
 
 
 
 
function BuyDropper:UpdatePriorityCache()
for priority, item in ipairs(self.list) do
self.idPriorityCache[item.id] = priority
end
end
 
 
 
 
function BuyDropper:UpdateDisplays()
if BuyDropperOptions:IsVisible() then
self:UpdateTrackingList()
end
 
if MerchantFrame:IsVisible() then
self:UpdateLabels()
end
end
 
 
 
 
--[[
Purchasing Methods
]]
 
function BuyDropper:ScanMerchant()
if self.db.profile.vendor.enabled and not self.hasPurchased then
local hasNeededItem
 
for index, item, priority in self:IterateTrackedMerchantItems() do
self:UpdatePrice(index, item)
if self:NumToBuy(item) > 0 then
self:QueuePurchase(index, priority)
hasNeededItem = true
end
end
 
if hasNeededItem then
if self.db.profile.vendor.confirm then
self:ConfirmPurchases()
else
self:ReleasePurchaseQueue()
end
 
if BuyDropperOptions:IsVisible() then
self:UpdateTrackingList()
end
end
 
if not self.hasWaited then
self:ScheduleEvent("BUYDROPPER_MERCHANT_WAIT", function()
self.hasWaited = true
end, BUYDROPPER_MERCHANT_DELAY)
end
end
end
 
 
 
 
function BuyDropper:IterateTrackedMerchantItems()
return function(num, index)
return self:TrackedItemIterator(num, index)
end,
GetMerchantNumItems(),
0
end
 
 
 
 
function BuyDropper:TrackedItemIterator(num, index)
while index < num do
index = index + 1
local link = GetMerchantItemLink(index)
if link then -- Sometimes info isn't available for all indexes right away
local item, priority = self:GetLinkItem(link)
if item then
return index, item, priority
end
else
return
end
end
end
 
 
 
 
function BuyDropper:UpdatePrice(index, item)
item.price, item.preset, item.available = select(3, GetMerchantItemInfo(index))
end
 
 
 
-- Adding patch from sag_ich_nicht from WoWInterface comments to fix version 0.9B4
function BuyDropper:NumToBuy(item)
if item.available ~= -1 then
--Item count is not -1, which means it's limited quantity. Determine available quantity and how much we want to buy.
local toBuy = min(item.amount - CogsBagSpace:GetBagItemCount(item.id), item.available)
if item.preset > 1 then
toBuy = (self.db.profile.overstock and ceil or floor)(toBuy/item.preset)
end
return toBuy
else
--Item count is -1, which means infinite quantity. Get amount we want and get out of here.
local toBuy = item.amount - CogsBagSpace:GetBagItemCount(item.id)
if item.preset > 1 then
toBuy = (self.db.profile.overstock and ceil or floor)(toBuy/item.preset)
end
 
return toBuy
end
end
 
 
 
 
function BuyDropper:ConfirmPurchases()
local which = "BUYDROPPER_CONFIRM_PURCHASE"
local dialog = StaticPopup_FindVisible(which)
if not dialog then
StaticPopup_Show(which, self:FormatMoney(self:GetQueueCost()))
else
getglobal(dialog:GetName().."Text"):SetText(format(StaticPopupDialogs[which].text, self:FormatMoney(self:GetQueueCost())))
end
end
 
 
 
 
function BuyDropper:PurchaseItem(item)
local num = self:NumToBuy(item)
local absoluteNum = num * item.preset
local cost = num * item.price
local link = self:MakeItemLink(item.id)
local db = self.db.profile
local budget = GetMoney() * (db.confirm and 1 or db.vendor.budget)
local ret = true
 
if cost > budget then
repeat
num = num - 1
cost = num * item.price
absoluteNum = num * item.preset
until cost < budget or num == 0
if num == 0 then
self:Print("Can't afford to buy %s × %d", link, absoluteNum)
return false
else
self:Print("Only able to afford %s × %d", link, absoluteNum)
ret = false
end
end
 
local space = self:CheckFreeSpace(item, num)
if space == 0 then
return false
elseif space < num then
num = space
cost = num * item.price
absoluteNum = num * item.preset
ret = false
end
 
self:Print("Buying %s × %d for %s", link, absoluteNum, self:FormatMoney(cost))
self:DoPurchase(item, num)
 
return ret
end
 
 
 
 
function BuyDropper:CheckFreeSpace(item, num)
local free, special = CogsBagSpace:FreeBagSpace(item.id)
free = floor((free + special) / item.preset)
if free == 0 then
self:Print("Not enough room in your bags for %s", self:MakeItemLink(item.id))
return 0
elseif free < num then
self:Print("Only able to fit %d more of %s into your bags", free * item.preset, self:MakeItemLink(item.id))
return free
end
return num
end
 
 
 
 
function BuyDropper:DoPurchase(item, num)
local numLoops, purchAmount, leftover
local stack = select(8, GetItemInfo(item.id))
if item.preset > 1 then
numLoops = num
purchAmount = 1
leftover = 0
else
numLoops = floor(num/stack)
purchAmount = stack
leftover = num % stack
end
 
for i = 1, numLoops do
BuyMerchantItem(item.index, purchAmount)
end
 
if leftover > 0 then
BuyMerchantItem(item.index, leftover)
end
end
 
 
 
 
--[[
General functions
]]
 
function BuyDropper:ExtractItemID(link)
return tonumber(strmatch(link, "item:(%d+):"))
end
 
 
 
 
function BuyDropper:MakeItemLink(id)
return (select(2, GetItemInfo(id)))
end
tags/0.9B5/images/dropper.jpg Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
tags/0.9B5/images/options.jpg Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
tags/0.9B5/images/confirm.jpg Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
tags/0.9B5/images/tracking.jpg Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes : Added: svn:mime-type + application/octet-stream
tags/0.9B5/BuyDropperOptions.lua New file
0,0 → 1,153
BDOPTS_REFILL_OPTIONS = "Refill Options"
BDOPTS_DROPPER_OPTIONS = "Vendor Dropper"
BDOPTS_CURRENTLY_TRACKING = "Currently Tracking"
BDOPTS_OPERATIONS = "Operations"
BDOPTS_SELECT = "Select"
BDOPTS_MODIFY = "Edit list"
BDOPTS_REMOVE_SELECTED = "Remove Selected"
BDOPTS_CLEAR_LIST = "Clear List"
BDOPTS_NOT_IMPLEMENTED = "Not implemented yet\nUse /buydropper list"
BDOPTS_ITEM_HEIGHT = 56
 
local optionsChecks = {
Vendor = { label = "Buy from vendors", parent = "vendor", field = "enabled" },
Confirm = { label = "Confirm purchase", parent = "vendor", field = "confirm" },
Bank = { label = "Withdraw from bank", field = "bank"},
Overstock = { label = "Overstock", field = "overstock", tooltipText = "Buy more than your set amount if the item comes in preset stacks" },
 
Dropper = { label = "Enable Dropper", parent = "dropper", field = "enabled" },
Label = { label = "Show Label", parent = "dropper", field = "label" },
}
 
function BuyDropper:OptionsLoad(this)
this:RegisterForDrag("LeftButton")
 
for which, options in pairs(optionsChecks) do
local button = getglobal("BuyDropper"..which.."Check")
local label = getglobal("BuyDropper"..which.."CheckText")
label:SetText(options.label)
button.tooltipText = options.tooltipText
button.db = { parent = options.parent, field = options.field }
end
 
BuyDropperPositionSliderHigh:SetText "Right"
BuyDropperPositionSliderLow:SetText "Left"
BuyDropperPositionSliderText:SetText "Position"
 
BuyDropperOptionsOperationsDropperLabel:SetText("Add an item")
BuyDropperOptionsOperationsDropperLabel:Anchor("RIGHT")
 
--[[local items = {}
 
items[1] = CreateFrame("Frame", "TrackingItem1", TrackingListScrollFrame, "BuyDropperTrackingItemButton")
items[1]:SetPoint("TOPLEFT", 42, 0)
for i = 2, 7 do
items[i] = CreateFrame("Frame", "TrackingItem"..i, TrackingListScrollFrame, "BuyDropperTrackingItemButton")
items[i]:SetPoint("TOPLEFT", items[i-1], "BOTTOMLEFT", 0, -8)
end
BuyDropperOptionsTrackingListScrollFrame:UpdateScrollChildRect()
self.trackingItems = items]]
end
 
 
 
 
function BuyDropper:OptionBoxLoad(this, title)
this:SetBackdropBorderColor(0.4, 0.4, 0.4)
this:SetBackdropColor(0.15, 0.15, 0.15)
getglobal(this:GetName().."Title"):SetText(title)
end
 
 
 
 
function BuyDropper:OptionsShow()
PlaySound("igMainMenuOption")
 
local db = self.db.profile
for which, options in pairs(optionsChecks) do
local checked = options.parent and db[options.parent][options.field] or db[options.field]
getglobal("BuyDropper"..which.."Check"):SetChecked(checked)
end
 
self:UpdateEnabled()
self:UpdateTrackingList()
end
 
 
 
 
function BuyDropper:SetCheckData(this)
local db, checked = self.db.profile, this:GetChecked()
db = this.db.parent and db[this.db.parent] or db
db[this.db.field] = checked and true or false -- GetChecked returns nil or 1, but nils aren't saved
end
 
 
 
 
function BuyDropper:UpdateEnabled()
local profile = self.db.profile
do
local checked = profile.vendor.enabled
if checked then
BlizzardOptionsPanel_CheckButton_Enable(BuyDropperConfirmCheck)
else
BlizzardOptionsPanel_CheckButton_Disable(BuyDropperConfirmCheck)
end
end
 
do
local unchecked = not profile.vendor.enabled and not profile.bank
if not unchecked then
BlizzardOptionsPanel_CheckButton_Enable(BuyDropperOverstockCheck)
else
BlizzardOptionsPanel_CheckButton_Disable(BuyDropperOverstockCheck)
end
end
 
do
checked = profile.dropper.enabled
if checked then
BlizzardOptionsPanel_Slider_Enable(BuyDropperPositionSlider)
BuyDropperPositionSlider:SetValue(profile.dropper.position)
BlizzardOptionsPanel_CheckButton_Enable(BuyDropperLabelCheck)
else
BlizzardOptionsPanel_Slider_Disable(BuyDropperPositionSlider)
BlizzardOptionsPanel_CheckButton_Disable(BuyDropperLabelCheck)
end
end
end
 
 
 
 
function BuyDropper:PositionSliderValueChanged(this)
if self.db then -- ValueChanged can occur before variables are loaded
self.db.profile.dropper.position = this:GetValue()
self:UpdateDropper()
end
end
 
 
 
 
function BuyDropper:UpdateTrackingList()
end
 
 
 
 
function BuyDropper:TrackingItemOnLoad(this)
local button = getglobal(this:GetName().."ItemButton")
 
button:SetScript("OnEnter", function(this)
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetText("Click to change tracking amount", 1, 1, 1, true)
GameTooltip:Show()
end)
 
button:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
end
tags/0.9B5/Ace2/Ace2.xml New file
0,0 → 1,10
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\..\UI.xsd">
<Script file="AceLibrary\AceLibrary.lua"/>
<Script file="AceOO-2.0\AceOO-2.0.lua"/>
<Script file="AceHook-2.1\AceHook-2.1.lua"/>
<Script file="AceEvent-2.0\AceEvent-2.0.lua"/>
<Script file="AceAddon-2.0\AceAddon-2.0.lua"/>
<Script file="AceConsole-2.0\AceConsole-2.0.lua"/>
<Script file="AceDB-2.0\AceDB-2.0.lua"/>
</Ui>
tags/0.9B5/Ace2 Property changes : Added: svn:externals + AceAddon-2.0 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceAddon-2.0 AceConsole-2.0 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceConsole-2.0 AceDB-2.0 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceDB-2.0 AceEvent-2.0 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceEvent-2.0 AceHook-2.1 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceHook-2.1 AceLibrary svn://svn.wowace.com/wow/ace2/mainline/trunk/AceLibrary AceOO-2.0 svn://svn.wowace.com/wow/ace2/mainline/trunk/AceOO-2.0
tags/0.9B5/BuyDropper.xml New file
0,0 → 1,434
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\UI.xsd">
<!-- ************************************************************************************
TEMPLATES
************************************************************************************ -->
 
<!-- Basic Dropper -->
<Button name="BuyDropperDropperTemplate" virtual="true">
<Size x="37" y="37"/>
<Layers>
<Layer level="BACKGROUND">
<Texture file="Interface\Buttons\UI-Slot-Background">
<Size x="39" y="39"/>
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="-2" y="2"/>
</Anchor>
</Anchors>
<TexCoords left="0" right="0.640625" top="0" bottom="0.640625"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<FontString name="$parentCount" inherits="NumberFontNormal" justifyH="RIGHT">
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset x="-5" y="2"/>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parentLabel" inherits="GameFontNormal" text="BUYDROPPER" justifyH="RIGHT"/>
</Layer>
<Layer level="BORDER">
<Texture name="$parentIconTexture"/>
</Layer>
</Layers>
<Scripts>
<OnLoad>
BuyDropper:DropperLoad(self)
</OnLoad>
<OnReceiveDrag>
BuyDropper:DropperClick(self)
</OnReceiveDrag>
<OnDragStart>
BuyDropper:DropperClick(self)
</OnDragStart>
<OnClick>
BuyDropper:DropperClick(self)
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
if self.link then
GameTooltip:SetHyperlink(self.link)
else
GameTooltip:SetText("Drag an item here to add it to BuyDropper", 1.0, 1.0, 1.0)
end
</OnEnter>
<OnLeave>
GameTooltip:Hide()
</OnLeave>
</Scripts>
<HighlightTexture alphaMode="ADD" file="Interface\Buttons\ButtonHilight-Square"/>
</Button>
 
<!-- Font used for tracking buttons -->
<Font name="NumberFontNormalGreen" inherits="NumberFontNormal" justifyH="RIGHT">
<FontHeight val="10"/>
<Color a="1" r="0.1" g="1.0" b="0.1"/>
</Font>
 
<!-- Tracking button template (instantiated in Lua) -->
<Button name="BuyDropperMerchantTracking" virtual="true" frameStrata="HIGH">
<Size x="30" y="16"/>
<Scripts>
<OnClick>
self:GetParent():Click()
BuyDropperMerchantDropper:Click()
</OnClick>
<OnEnter>
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetText("BuyDropper")
GameTooltip:AddLine("You are currently tracking "..self:GetText().." of this item. Click to change.", 1, 1, 1, 1)
GameTooltip:Show()
</OnEnter>
<OnLeave>
GameTooltip:Hide()
</OnLeave>
</Scripts>
<ButtonText font="NumberFontNormalGreen">
<Anchors>
<Anchor point="TOPRIGHT"/>
</Anchors>
</ButtonText>
</Button>
 
<!-- Tracking List Items -->
<Button name="BuyDropperTrackingItemButton" virtual="true" inherits="MerchantItemTemplate">
<Frames>
<CheckButton name="$parentSelectCheck" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="RIGHT" relativePoint="LEFT">
<Offset x="-5" y="0"/>
</Anchor>
</Anchors>
<HitRectInsets left="0" right="0" top="0" bottom="0"/>
</CheckButton>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:TrackingItemOnLoad(self)
</OnLoad>
</Scripts>
</Button>
 
<CheckButton name="BuyDropperCheck" virtual="true" inherits="OptionsCheckButtonTemplate">
<Scripts>
<OnClick>
BuyDropper:SetCheckData(self)
BuyDropper:UpdateEnabled()
BuyDropper:UpdateDropper()
</OnClick>
</Scripts>
</CheckButton>
 
 
<!-- ************************************************************************************
FRAMES
************************************************************************************ -->
 
<!-- Position of this dropper is set by Lua based on saved variables -->
<Button name="BuyDropperMerchantDropper" parent="MerchantFrame" inherits="BuyDropperDropperTemplate"/>
 
<!-- Options Frame -->
<Frame name="BuyDropperOptions" toplevel="true" frameStrata="DIALOG" movable="true" enableMouse="true" hidden="true" parent="UIParent">
<Size x="450" y="450"/>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<BackgroundInsets>
<AbsInset left="11" right="12" top="12" bottom="11"/>
</BackgroundInsets>
<TileSize>
<AbsValue val="32"/>
</TileSize>
<EdgeSize>
<AbsValue val="32"/>
</EdgeSize>
</Backdrop>
<Layers>
<Layer level="ARTWORK">
<Texture name="$parentHeader" file="Interface\DialogFrame\UI-DialogBox-Header">
<Size x="256" y="64"/>
<Anchors>
<Anchor point="TOP">
<Offset x="0" y="12"/>
</Anchor>
</Anchors>
</Texture>
<FontString inherits="GameFontNormal" text="BUYDROPPER">
<Anchors>
<Anchor point="TOP" relativeTo="$parentHeader">
<Offset x="0" y="-14"/>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Frame name="$parentRefillOptions" inherits="OptionsBoxTemplate">
<Size x="200" y="132"/>
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="12" y="-39"/>
</Anchor>
</Anchors>
<Frames>
<CheckButton name="BuyDropperVendorCheck" inherits="BuyDropperCheck">
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="10" y="-11"/>
</Anchor>
</Anchors>
</CheckButton>
<CheckButton name="BuyDropperConfirmCheck" inherits="BuyDropperCheck">
<Size x="26" y="26"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperVendorCheck" relativePoint="BOTTOMLEFT">
<Offset x="5" y="4"/>
</Anchor>
</Anchors>
</CheckButton>
<CheckButton name="BuyDropperBankCheck" inherits="BuyDropperCheck">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperConfirmCheck" relativePoint="BOTTOMLEFT">
<Offset x="-5" y="4"/>
</Anchor>
</Anchors>
</CheckButton>
<CheckButton name="BuyDropperOverstockCheck" inherits="BuyDropperCheck">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperBankCheck" relativePoint="BOTTOMLEFT">
<Offset x="0" y="4"/>
</Anchor>
</Anchors>
</CheckButton>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:OptionBoxLoad(self, BDOPTS_REFILL_OPTIONS)
</OnLoad>
</Scripts>
</Frame>
<Frame name="$parentDropperOptions" inherits="OptionsBoxTemplate">
<Size x="200" y="117"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRefillOptions" relativePoint="BOTTOMLEFT">
<Offset x="0" y="-20"/>
</Anchor>
</Anchors>
<Frames>
<CheckButton name="BuyDropperDropperCheck" inherits="BuyDropperCheck">
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="10" y="-11"/>
</Anchor>
</Anchors>
</CheckButton>
<Slider name="BuyDropperPositionSlider" inherits="OptionsSliderTemplate" minValue="70" maxValue="306" valueStep="1" defaultValue="70">
<Size x="160" y="17"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperDropperCheck" relativePoint="BOTTOMLEFT">
<Offset x="10" y="-6"/>
</Anchor>
</Anchors>
<Scripts>
<OnValueChanged>
BuyDropper:PositionSliderValueChanged(self)
</OnValueChanged>
</Scripts>
</Slider>
<CheckButton name="BuyDropperLabelCheck" inherits="BuyDropperCheck">
<Size x="26" y="26"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperPositionSlider" relativePoint="BOTTOMLEFT">
<Offset x="-5" y="-10"/>
</Anchor>
</Anchors>
</CheckButton>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:OptionBoxLoad(self, BDOPTS_DROPPER_OPTIONS)
</OnLoad>
</Scripts>
</Frame>
<Frame name="$parentTrackingList" inherits="OptionsBoxTemplate">
<Size x="225" y="269"/>
<Anchors>
<Anchor point="TOPRIGHT">
<Offset x="-12" y="-39"/>
</Anchor>
</Anchors>
<Layers>
<Layer>
<FontString text="BDOPTS_NOT_IMPLEMENTED" inherits="GameFontDisable">
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<ScrollFrame name="$parentScrollFrame" inherits="UIPanelScrollFrameTemplate">
<Size x="194" y="256"/>
<Anchors>
<Anchor point="TOP">
<Offset x="-16" y="-8"/>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<Texture file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
<Size x="31" y="256"/>
<Anchors>
<Anchor point="TOPLEFT" relativePoint="TOPRIGHT">
<Offset x="-2" y="5"/>
</Anchor>
</Anchors>
<TexCoords left="0" right="0.484375" top="0" bottom="1.0"/>
</Texture>
<Texture file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
<Size x="31" y="106"/>
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT">
<Offset x="-2" y="-2"/>
</Anchor>
</Anchors>
<TexCoords left="0.515625" right="1.0" top="0" bottom="0.4140625"/>
</Texture>
</Layer>
</Layers>
<ScrollChild>
<Frame name="TrackingListScrollFrame">
<!-- Tracking items will be instantiated in Lua -->
<Size x="1" y="1"/><!-- Dummy size so it'll show at all -->
</Frame>
</ScrollChild>
</ScrollFrame>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:OptionBoxLoad(self, BDOPTS_CURRENTLY_TRACKING)
</OnLoad>
</Scripts>
</Frame>
<Frame name="$parentOperations" inherits="OptionsBoxTemplate">
<Size x="425" y="80"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentDropperOptions" relativePoint="BOTTOMLEFT">
<Offset x="0" y="-20"/>
</Anchor>
</Anchors>
<Layers>
<Layer level="OVERLAY">
<FontString name="BuyDropperOptionsSelectLabel" inherits="GameFontNormal" text="BDOPTS_SELECT">
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="206" y="-7"/>
</Anchor>
</Anchors>
</FontString>
<FontString name="BuyDropperOptionsModifyLabel" inherits="GameFontNormal" text="BDOPTS_MODIFY">
<Anchors>
<Anchor point="LEFT" relativeTo="BuyDropperOptionsSelectLabel" relativePoint="RIGHT">
<Offset x="38" y="0"/>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="$parentDropper" inherits="BuyDropperDropperTemplate">
<Anchors>
<Anchor point="TOPLEFT">
<Offset x="15" y="-22"/>
</Anchor>
</Anchors>
</Button>
<Button name="$parentSelectAll" inherits="UIPanelButtonTemplate" text="ALL">
<Size x="60" y="24"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperOptionsSelectLabel" relativePoint="BOTTOMLEFT">
<Offset x="7" y="-3"/>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
self:Disable()
</OnLoad>
</Scripts>
</Button>
<Button name="$parentSelectNone" inherits="UIPanelButtonTemplate" text="NONE">
<Size x="60" y="24"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentSelectAll" relativePoint="BOTTOMLEFT"/>
</Anchors>
<Scripts>
<OnLoad>
self:Disable()
</OnLoad>
</Scripts>
</Button>
<Button name="$parentRemoveSelected" inherits="UIPanelButtonTemplate" text="BDOPTS_REMOVE_SELECTED">
<Size x="125" y="24"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="BuyDropperOptionsModifyLabel" relativePoint="BOTTOMLEFT">
<Offset x="7" y="-3"/>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
self:Disable()
</OnLoad>
</Scripts>
</Button>
<Button name="$parentClearList" inherits="UIPanelButtonTemplate" text="BDOPTS_CLEAR_LIST">
<Size x="125" y="24"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentRemoveSelected" relativePoint="BOTTOMLEFT"/>
</Anchors>
<Scripts>
<OnClick>
StaticPopup_Show("BUYDROPPER_CONFIRM_CLEAR")
</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:OptionBoxLoad(self, BDOPTS_OPERATIONS)
</OnLoad>
</Scripts>
</Frame>
<Button name="$parentCloseButton" inherits="UIPanelButtonTemplate2" text="CLOSE">
<Size x="72" y="24"/>
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset x="-16" y="16"/>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
PlaySound("gsTitleOptionExit")
self:GetParent():Hide()
</OnClick>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnLoad>
BuyDropper:OptionsLoad(self)
</OnLoad>
<OnShow>
BuyDropper:OptionsShow()
</OnShow>
<OnDragStart>
self:StartMoving()
</OnDragStart>
<OnDragStop>
self:StopMovingOrSizing()
</OnDragStop>
</Scripts>
</Frame>
</Ui>
\ No newline at end of file
tags/0.9B5/BuyDropper.lua New file
0,0 → 1,306
--[[ BuyDropper - By Cogwheel
Inspired by FreeRefills by Kyahx ]]
 
BUYDROPPER = "BuyDropper"
DROPPER_MIN_X = 70
DROPPER_MAX_X = 306
 
BuyDropper = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceHook-2.1", "AceConsole-2.0", "AceDB-2.0")
 
function BuyDropper:OnInitialize()
self:InitDB() -- Set up saved variables
self:InitConsole() -- Create slash commands
self:InitPopup() -- Create amount entry popup dialog
self:InitLabels() -- Create tracking labels in merchant window
self:InitPurchaseQueue()-- Initialization for the purchase queue
self:UpdateDropper() -- Position the Merchant Dropper based on saved preferences
end
 
 
 
 
function BuyDropper:InitDB()
self:RegisterDB("BuyDropperDB")
 
self:RegisterDefaults("char", {
profile = "char"
})
 
self:RegisterDefaults("profile", {
list = {},
vendor = {
enabled = true,
confirm = true,
budget = 0.50,
fallthrough = false
},
bank = true,
overstock = false,
dropper = {
enabled = true,
position = DROPPER_MAX_X,
label = true
},
})
 
self:SetProfile(self.db.char.profile)
end
 
 
 
 
function BuyDropper:InitPopup()
StaticPopupDialogs["BUYDROPPER_ASK_AMOUNT"] = {
text = "Please enter the amount of this item would you like to keep in stock:",
button1 = ACCEPT,
button2 = CANCEL,
hasEditBox = 1,
maxLetters = 5,
timeout = 0,
OnAccept = function()
self:AcceptAmount(this:GetParent().data, tonumber(getglobal(this:GetParent():GetName().."EditBox"):GetText()))
end,
OnCancel = function()
end,
OnShow = function()
local name = this:GetName()
getglobal(name.."EditBox"):SetText("")
getglobal(name.."Button1"):Disable()
getglobal(name.."EditBox"):SetFocus()
end,
OnHide = function()
getglobal(this.data:GetName().."IconTexture"):SetTexture(nil)
this.data.link = nil
end,
EditBoxOnTextChanged = function()
local name = this:GetParent():GetName()
local button = getglobal(name.."Button1")
if tonumber(getglobal(name.."EditBox"):GetText()) then
button:Enable()
else
button:Disable()
end
end,
EditBoxOnEnterPressed = function()
if getglobal(this:GetParent():GetName().."Button1"):IsEnabled() then
self:AcceptAmount(this:GetParent().data, tonumber(getglobal(this:GetParent():GetName().."EditBox"):GetText()))
end
this:GetParent():Hide()
end,
}
 
StaticPopupDialogs["BUYDROPPER_CONFIRM_PURCHASE"] = {
text = "BuyDropper would like to buy items from this vendor totaling %s. Proceed?",
button1 = YES,
button2 = NO,
OnAccept = function()
self:ReleasePurchaseQueue()
end,
timeout = 0,
hideOnEscape = true,
}
 
StaticPopupDialogs["BUYDROPPER_CONFIRM_CLEAR"] = {
text = "Are you sure you want to clear your BuyDropper tracking list?",
button1 = YES,
button2 = NO,
OnAccept = function()
self:ClearTrackingList()
end,
timeout = 0,
hideOnEscape = true,
}
end
 
 
 
 
function BuyDropper:InitLabels()
local labels = {}
 
for i=1,10 do
labels[i] = CreateFrame("Button", nil, getglobal("MerchantItem"..i.."ItemButton"), "BuyDropperMerchantTracking")
labels[i]:SetPoint("TOPRIGHT", getglobal("MerchantItem"..i.."ItemButtonCount"), "BOTTOMRIGHT")
 
labels[i].Update = function(this)
local link = GetMerchantItemLink(this:GetParent():GetID())
local item = link and self:GetLinkItem(link)
if item and self.enabled then
this:SetText(item.amount)
this:Show()
else
this:Hide()
end
end
end
 
self.merchantLabels = labels
end
 
 
 
 
function BuyDropper:UpdateDropper()
local db = self.db.profile.dropper
local dropper = BuyDropperMerchantDropper
local label = BuyDropperMerchantDropperLabel
 
if db.enabled then
dropper:Show()
dropper:ClearAllPoints()
dropper:SetPoint("TOPLEFT", db.position, -36)
 
label:Anchor(db.position < label:GetWidth() + 70 and "RIGHT" or "LEFT")
 
if db.label then
label:Show()
else
label:Hide()
end
else
dropper:Hide()
end
end
 
 
 
 
function BuyDropper:OnEnable()
self.enabled = true
 
-- These two hooks are only necessary until GetCursorInfo returns data for merchant items
self:SecureHook("PickupMerchantItem", function(index)
self.link = GetMerchantItemLink(index)
end)
self:SecureHook("ClearCursor", function()
self.link = nil
end)
 
self:SecureHook("MerchantFrame_UpdateMerchantInfo", "UpdateLabels")
self:RegisterEvent("MERCHANT_SHOW", function()
for i, item in ipairs(self.list) do
item.priority = nil
item.index = nil
end
self:ScanMerchant()
end)
self:RegisterEvent("MERCHANT_UPDATE", "ScanMerchant")
self:RegisterEvent("MERCHANT_CLOSED", "Cleanup")
 
self.list = self.db.profile.list
self.idPriorityCache = {}
self:UpdatePriorityCache()
self:UpdateLabels()
 
if MerchantFrame:IsVisible() then
self:ScanMerchant()
end
end
 
 
 
 
function BuyDropper:OnDisable()
self.enabled = nil
self:UpdateDropper()
self:UpdateLabels()
self:Cleanup()
end
 
 
 
 
function BuyDropper:Cleanup()
StaticPopup_Hide("BUYDROPPER_ASK_AMOUNT")
StaticPopup_Hide("BUYDROPPER_CONFIRM_PURCHASE")
self:ClearPurchaseQueue()
self.hasPurchased = nil
end
 
 
 
 
function BuyDropper:DropperLoad(this)
this:RegisterForDrag "LeftButton"
local label = getglobal(this:GetName().."Label")
 
if not self.labelAnchors then
self.labelAnchors = {
LEFT = {
point = "RIGHT",
relative = "LEFT",
offX = -4
},
RIGHT = {
point = "LEFT",
relative = "RIGHT",
offX = 2
}
}
end
function label.Anchor(this, which)
which = which and which:upper() or ""
local t = self.labelAnchors[which]
this:ClearAllPoints()
this:SetPoint(t.point, this:GetParent(), t.relative, t.offX, 0)
end
 
label:Anchor("LEFT")
end
 
 
 
 
function BuyDropper:DropperClick(this)
local which, id, link = GetCursorInfo()
if not link then -- Only until GetCursorInfo returns data for merchant items
link = self.link
which = "item"
end
if not link or which ~= "item" then
return
end
 
this.link = link
local texture = select(10, GetItemInfo(link))
getglobal(this:GetName().."IconTexture"):SetTexture(texture)
 
ClearCursor()
 
local dialog = StaticPopup_Show("BUYDROPPER_ASK_AMOUNT")
dialog.data = this
end
 
 
 
 
function BuyDropper:AcceptAmount(button, amount)
if amount > 0 then
self:AddTrackingItem(button.link, amount)
else
self:RemoveTrackingItem(select(2, self:GetLinkItem(button.link)))
end
end
 
 
 
 
function BuyDropper:UpdateLabels()
for i, label in ipairs(self.merchantLabels) do
label:Update()
end
end
 
 
 
 
function BuyDropper:FormatMoney(copper)
local gold = floor(copper / COPPER_PER_GOLD)
local silver = floor(copper / COPPER_PER_SILVER) % SILVER_PER_GOLD
copper = copper % COPPER_PER_SILVER
 
return format( "|cFFEEDD00%s|r|cFFBBBBBB%s|r|cFFDD6633%s|r",
gold > 0 and gold.."g"..((silver > 0 or copper > 0) and " " or "") or "",
silver > 0 and silver.."s"..(copper > 0 and " " or "") or "",
copper > 0 and copper.."c" or "")
end
tags/0.9B5/BuyDropperConsole.lua New file
0,0 → 1,347
function BuyDropper:InitConsole()
self:RegisterChatCommand({"/buydropper", "/bd"}, {type = "group", args = {
 
options = {
type = "execute",
name = "Options",
desc = "Open the BuyDropper options window",
func = function()
BuyDropperOptions:Show()
end
},
 
 
 
 
add = {
type = "text",
name = "Add Item",
desc = "Add an item to the tracking list (also changes amount of existing items)",
usage = "<item link> <amount>",
validate = function(text)
local link, amount = self:ParseAddCommand(text)
return link and amount > 0
end,
get = false,
set = function(text)
local link, amount = self:ParseAddCommand(text)
self:AddTrackingItem(link, amount)
end
},
 
 
 
 
list = {
type = "execute",
name = "List Items",
desc = "List the items you are currently tracking (high to low priority)",
func = function()
local message = "Currently Tracking:"
if #self.list == 0 then
message = message.."\n Nothing"
end
for priority, item in ipairs(self.list) do
message = message..format("\n%4d: %s × %s", priority, self:MakeItemLink(item.id), item.amount)
end
self:Print(message)
end
},
 
 
 
 
change = {
type = "text",
name = "Change Amount Tracked",
desc = "Change the tracked amount of an item",
usage = "<priority> <amount>\n"..
" <priority> is obtained from /buydropper list\n"..
" <amount> must be 1 or more",
input = true,
validate = function(priority, amount)
priority, amount = tonumber(priority), tonumber(amount)
return priority and amount and priority >= 1 and priority <= #self.list and amount >= 1
end,
get = false,
set = function(priority, amount)
self:ChangeTrackingItem(tonumber(priority), tonumber(amount))
end
},
 
 
 
 
priority = {
type = "text",
name = "Set Item Priority",
desc = "Change an item's priority",
usage = "<current priority> <new priority>\n"..
" <current priority> is obtained from /buydropper list\n"..
" <new priority> must be a number from 1 to the number of items you are tracking",
input = true,
validate = function(old, new)
old, new = tonumber(old), tonumber(new)
return old and new and old >= 1 and old <= #self.list and new >= 1 and new <= #self.list
end,
get = false,
set = function(old, new)
self:SetTrackingPriority(tonumber(old), tonumber(new))
end
},
 
 
 
 
remove = {
type = "text",
name = "Remove Item",
desc = "Remove an item from your tracking list",
usage = "<index>\n"..
" <index> is obtained from /buydropper list",
validate = function(index)
index = tonumber(index)
return index and index > 0 and index <= #self.list
end,
get = false,
set = function(index)
self:RemoveTrackingItem(tonumber(index))
end
},
 
 
 
 
clear = {
type = "execute",
name = "Clear List",
desc = "Remove all items from your tracking list",
func = function()
StaticPopup_Show("BUYDROPPER_CONFIRM_CLEAR")
end
},
 
 
 
 
vendor = {
type = "group",
name = "Vendor Options",
desc = "Options for vendor purchases",
args = {
toggle = {
type = "toggle",
name = "Toggle Purchase",
desc = "Toggles the automatic purchase of items from vendors",
map = { [true] = GREEN_FONT_COLOR_CODE.."Enabled|r", [false] = RED_FONT_COLOR_CODE.."Disabled|r" },
get = function()
return self.db.profile.vendor.enabled
end,
set = function(value)
self.db.profile.vendor.enabled = value
if BuyDropperOptions:IsVisible() then
BuyDropperVendorCheck:SetChecked(value)
end
self:UpdateEnabled()
end
},
 
 
 
 
confirm = {
type = "toggle",
name = "Confirm Purchases",
desc = "Toggles whether to confirm purchases from vendors",
map = { [true] = GREEN_FONT_COLOR_CODE.."Yes|r", [false] = RED_FONT_COLOR_CODE.."No|r" },
disabled = function()
return not self.db.profile.vendor.enabled
end,
get = function()
return self.db.profile.vendor.confirm
end,
set = function(value)
self.db.profile.vendor.confirm = value
if BuyDropperOptions:IsVisible() then
BuyDropperConfirmCheck:SetChecked(value)
end
end
},
 
 
 
 
budget = {
type = "range",
name = "Budget",
desc = "Sets the percentage of your total money BuyDropper is allowed to use to purchase an item",
min = .01, max = 1,
isPercent = true,
disabled = function()
return not self.db.profile.vendor.enabled
end,
get = function()
return self.db.profile.vendor.budget
end,
set = function(value)
self.db.profile.vendor.budget = value
end
},
 
 
 
 
fallthrough = {
type = "toggle",
name = "Fall-through Purchases",
desc = "Toggles whether to purchase lower-priority items when higher-priority items cannot be purchased",
map = { [true] = GREEN_FONT_COLOR_CODE.."Enabled|r", [false] = RED_FONT_COLOR_CODE.."Disabled|r" },
disabled = function()
return not self.db.profile.vendor.enabled
end,
get = function()
return self.db.profile.vendor.fallthrough
end,
set = function(value)
self.db.profile.vendor.fallthrough = value
end
}
}
},
 
 
 
 
bank = {
type = "toggle",
name = "Withdraw Items",
desc = "Toggles whether to withdraw items from your bank",
map = { [true] = GREEN_FONT_COLOR_CODE.."Yes|r", [false] = RED_FONT_COLOR_CODE.."No|r" },
get = function()
return self.db.profile.bank
end,
set = function(value)
self.db.profile.bank = value
if BuyDropperOptions:IsVisible() then
BuyDropperBankCheck:SetChecked(value)
end
self:UpdateEnabled()
end
},
 
 
 
 
overstock = {
type = "toggle",
name = "Overstock Items",
desc = "Toggles whether to overstock items that come in preset stacks (like food and water)",
map = { [true] = GREEN_FONT_COLOR_CODE.."Yes|r", [false] = RED_FONT_COLOR_CODE.."No|r" },
disabled = function()
local data = self.db.profile
return not data.bank and not data.vendor.enabled
end,
get = function()
return self.db.profile.overstock
end,
set = function(value)
self.db.profile.overstock = value
if BuyDropperOptions:IsVisible() then
BuyDropperOverstockCheck:SetChecked(value)
end
end
},
 
 
 
 
dropper = {
type = "group",
name = "Vendor Dropper Options",
desc = "Options for the dropper in vendor windows",
args = {
toggle = {
type = "toggle",
name = "Toggle Vendor Dropper",
desc = "Toggles whether to show a dropper in vendor windows",
map = { [true] = GREEN_FONT_COLOR_CODE.."Enabled|r", [false] = RED_FONT_COLOR_CODE.."Disabled|r" },
get = function()
return self.db.profile.dropper.enabled
end,
set = function(value)
self.db.profile.dropper.enabled = value
if BuyDropperOptions:IsVisible() then
BuyDropperDropperCheck:SetChecked(value)
end
self:UpdateEnabled()
 
if MerchantFrame:IsVisible() then
self:UpdateDropper()
end
end
},
 
 
 
 
position = {
type = "range",
name = "Dropper Position",
desc = "Sets the horizontal position of the dropper in vendor windows (0 = left, 100 = right)",
min = 0, max = 100,
disabled = function()
return not self.db.profile.dropper.enabled
end,
get = function()
return (self.db.profile.dropper.position - DROPPER_MIN_X) / (DROPPER_MAX_X - DROPPER_MIN_X) * 100
end,
set = function(value)
local newValue = value / 100 * (DROPPER_MAX_X - DROPPER_MIN_X) + DROPPER_MIN_X
self.db.profile.dropper.position = newValue
if BuyDropperOptions:IsVisible() then
BuyDropperPositionSlider:SetValue(newValue)
end
 
if MerchantFrame:IsVisible() then
self:UpdateDropper()
end
end
},
 
 
 
 
label = {
type = "toggle",
name = "Toggle Dropper Label",
desc = "Toggles visibility of the vendor dropper's label",
disabled = function()
return not self.db.profile.dropper.enabled
end,
get = function()
return self.db.profile.dropper.label
end,
set = function(value)
self.db.profile.dropper.label = value
if BuyDropperOptions:IsVisible() then
BuyDropperLabelCheck:SetChecked(value)
end
 
if MerchantFrame:IsVisible() then
self:UpdateDropper()
end
end
}
}
},
 
}})end
 
 
 
 
function BuyDropper:ParseAddCommand(text)
local link, amount = strmatch(strtrim(text), "^(|c%x-|Hitem:%-?%d+:%-?%d+:%-?%d+:%-?%d+:%-?%d+:%-?%d+:%-?%d+:%-?%d+|h%[.-%]|h|r)%s-(%d+)$")
amount = tonumber(amount)
return link, amount
end
tags/0.9B5/BuyDropper.toc New file
0,0 → 1,19
## Interface: 32000
## Author: Cogwheel, maintained by Ellira
## Title: BuyDropper
## Version: 0.9B5
## Notes: Keeps you stocked with items from merchants or your bank.
## X-Website: http://cogwheel.info
## X-Category: Inventory
## SavedVariables: BuyDropperDB
## OptionalDeps: CogsBagSpace, Ace2
 
Ace2\Ace2.xml
CogsBagSpace\CogsBagSpace.lua
 
BuyDropper.lua
BuyDropperEngine.lua
BuyDropperOptions.lua
BuyDropperConsole.lua
BuyDropperQueue.lua
BuyDropper.xml
\ No newline at end of file
tags/0.9B5 Property changes : Added: svn:ignore + .project Added: svn:externals + CogsBagSpace svn://eternalblue.dnsalias.net/public/CogsBagSpace/trunk