annotate Modules/Events.lua @ 99:e9b903cf9b33

Added a menu to allow the user to see what is to be crafted, only what you hae mats for, or view everything so you can see why something isn't to be crafted.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Thu, 19 Aug 2010 23:14:30 -0700
parents 028c02f1d47f
children c59d22fac6d1
rev   line source
Asa@63 1 local ItemAuditor = select(2, ...)
Asa@63 2 local Events = ItemAuditor:NewModule("Events", "AceEvent-3.0")
Asa@3 3
Asa@92 4 local Utils = ItemAuditor:GetModule("Utils")
Asa@92 5
Asa@63 6 function ItemAuditor:OnEnable()
Asa@3 7 self:RegisterEvent("MAIL_SHOW")
Asa@4 8 self:RegisterEvent("UNIT_SPELLCAST_START")
Asa@81 9
Asa@81 10 self:RegisterEvent("BANKFRAME_OPENED", 'BankFrameChanged')
Asa@81 11 self:RegisterEvent("BANKFRAME_CLOSED", 'BankFrameChanged')
Asa@81 12
Asa@63 13 ItemAuditor:UpdateCurrentInventory()
Asa@3 14 self:WatchBags()
Asa@9 15
Asa@63 16 self:SetEnabled(nil, self.db.profile.ItemAuditor_enabled)
Asa@38 17 end
Asa@38 18
Asa@63 19 function ItemAuditor:OnDisable()
Asa@38 20 self:UnwatchBags()
Asa@38 21 self:UnregisterAllEvents()
Asa@63 22 ItemAuditor:HideAllFrames()
Asa@3 23 end
Asa@3 24
Asa@63 25 function ItemAuditor:MAIL_SHOW()
Asa@3 26 self:Debug("MAIL_SHOW")
Asa@39 27 self:UnwatchBags()
Asa@63 28 ItemAuditor:UpdateCurrentInventory()
Asa@3 29 self.lastMailScan = self:ScanMail()
Asa@7 30
Asa@3 31 self:UnregisterEvent("MAIL_SHOW")
Asa@3 32 self:RegisterEvent("MAIL_CLOSED")
Asa@3 33 self:RegisterEvent("MAIL_INBOX_UPDATE")
Asa@39 34
Asa@39 35 self:GenerateBlankOutbox()
Asa@39 36
Asa@39 37 self:RegisterEvent("MAIL_SUCCESS")
Asa@39 38 end
Asa@39 39
Asa@63 40 function ItemAuditor:GenerateBlankOutbox()
Asa@39 41 self.mailOutbox = {
Asa@39 42 from = UnitName("player"),
Asa@39 43 to = "",
Asa@39 44 subject = "",
Asa@39 45 link = '',
Asa@39 46 count = 0,
Asa@39 47 COD = 0,
Asa@39 48 key = random(10000),
Asa@39 49 sent = 0,
Asa@39 50 }
Asa@39 51
Asa@39 52 if self.db.factionrealm.outbound_cod[self.mailOutbox.key] ~= nil then
Asa@39 53 return self:GenerateBlankOutbox()
Asa@39 54 end
Asa@39 55 end
Asa@39 56
Asa@40 57 local attachedItems = {}
Asa@39 58 local Orig_SendMail = SendMail
Asa@42 59 local skipCODTracking = false
Asa@92 60 local skipCODCheck = false
Asa@42 61
Asa@42 62 StaticPopupDialogs["ItemAuditor_Send_COD_without_tracking_number"] = {
Asa@42 63 text = "ItemAuditor cannot track COD mail with multiple item types attached. Do you want to send this mail without tracking?",
Asa@42 64 button1 = "Yes",
Asa@42 65 button2 = "No",
Asa@42 66 OnAccept = function()
Asa@42 67 skipCODTracking = true
Asa@42 68 end,
Asa@42 69 timeout = 0,
Asa@42 70 whileDead = true,
Asa@42 71 hideOnEscape = true,
Asa@42 72 }
Asa@39 73
Asa@92 74 StaticPopupDialogs["ItemAuditor_Insufficient_COD"] = {
Asa@92 75 text = "The COD on this mail is less than the value of items attached. Are you sure you want to send this?|nTotal value (including postage): %s",
Asa@92 76 button1 = "Yes",
Asa@92 77 button2 = "No",
Asa@92 78 OnAccept = function()
Asa@92 79 skipCODCheck = true
Asa@92 80 end,
Asa@92 81 timeout = 0,
Asa@92 82 whileDead = true,
Asa@92 83 hideOnEscape = true,
Asa@92 84 }
Asa@92 85
Asa@39 86 function SendMail(recipient, subject, body, ...)
Asa@39 87 local self = ItemAuditor
Asa@39 88 self:GenerateBlankOutbox()
Asa@39 89
Asa@39 90 self:Debug(format("[To: %s] [Subject: %s]", recipient, subject))
Asa@39 91
Asa@39 92 self.mailOutbox.COD = GetSendMailCOD()
Asa@39 93
Asa@92 94 wipe(attachedItems)
Asa@40 95 local totalStacks = 0
Asa@39 96 local link
Asa@40 97 for index = 1, ATTACHMENTS_MAX_SEND do
Asa@39 98 local itemName, _, itemCount = GetSendMailItem(index)
Asa@39 99 local newLink = GetSendMailItemLink(index)
Asa@39 100
Asa@40 101 if newLink ~= nil then
Asa@40 102 newLink = self:GetSafeLink(newLink)
Asa@40 103 totalStacks = totalStacks + 1
Asa@40 104 attachedItems[newLink] = (attachedItems[newLink] or {stacks = 0, count = 0})
Asa@40 105 attachedItems[newLink].stacks = attachedItems[newLink].stacks + 1
Asa@40 106 attachedItems[newLink].count = attachedItems[newLink].count + itemCount
Asa@40 107 attachedItems[newLink].price = 0 -- This is a placeholder for below.
Asa@39 108 end
Asa@40 109 end
Asa@92 110 local attachedValue = 0
Asa@40 111 for link, data in pairs(attachedItems) do
Asa@53 112 data.price = 30 * data.stacks
Asa@92 113 attachedValue = attachedValue + data.price + (select(2, ItemAuditor:GetItemCost(link)) * data.stacks)
Asa@40 114 end
Asa@40 115
Asa@92 116 local cross_account_mail = true
Asa@92 117 for name, _ in pairs(DataStore:GetCharacters()) do
Asa@97 118 if strlower(recipient) == strlower(name) then
Asa@92 119 cross_account_mail = false
Asa@92 120 break
Asa@92 121 end
Asa@92 122 end
Asa@92 123 if cross_account_mail and attachedValue > self.mailOutbox.COD and not skipCODCheck then
Asa@92 124 self:GenerateBlankOutbox()
Asa@92 125 skipCODCheck = false;
Asa@92 126 local vararg = ...
Asa@92 127 StaticPopupDialogs["ItemAuditor_Insufficient_COD"].OnAccept = function()
Asa@92 128 skipCODCheck = true
Asa@92 129 SendMail(recipient, subject, body, vararg)
Asa@92 130 skipCODCheck = false
Asa@92 131 end
Asa@92 132 StaticPopup_Show ("ItemAuditor_Insufficient_COD", Utils.FormatMoney(attachedValue));
Asa@92 133 return
Asa@92 134 elseif self.mailOutbox.COD > 0 and skipCODTracking then
Asa@42 135
Asa@42 136 elseif self.mailOutbox.COD > 0 then
Asa@40 137 if self:tcount(attachedItems) > 1 then
Asa@39 138 self:GenerateBlankOutbox()
Asa@42 139 local vararg = ...
Asa@42 140 StaticPopupDialogs["ItemAuditor_Send_COD_without_tracking_number"].OnAccept = function()
Asa@42 141 skipCODTracking = true
Asa@42 142 SendMail(recipient, subject, body, vararg)
Asa@42 143 skipCODTracking = false
Asa@42 144 end
Asa@42 145 StaticPopup_Show ("ItemAuditor_Send_COD_without_tracking_number");
Asa@39 146 return
Asa@39 147 end
Asa@40 148 self:Debug("COD mail")
Asa@39 149
Asa@40 150 subject = format("[IA: %s] %s", self.mailOutbox.key, subject)
Asa@40 151 self.mailOutbox.subject = subject
Asa@40 152 self.mailOutbox.to = recipient
Asa@40 153
Asa@40 154 -- At this point we know there is only one item
Asa@40 155 for link, data in pairs(attachedItems) do
Asa@40 156 self.mailOutbox.link = link
Asa@40 157 self.mailOutbox.count = data.count
Asa@40 158 end
Asa@40 159 else
Asa@40 160 self:Debug("Non-COD mail")
Asa@39 161 end
Asa@40 162
Asa@39 163 return Orig_SendMail(recipient, subject, body, ...)
Asa@39 164 end
Asa@39 165
Asa@63 166 function ItemAuditor:MAIL_SUCCESS(event)
Asa@42 167 skipCODTracking = false
Asa@92 168 skipCODCheck = false
Asa@92 169
Asa@40 170 for link, data in pairs(attachedItems) do
Asa@40 171 self:SaveValue(link, data.price, data.count)
Asa@40 172 end
Asa@39 173 if self.mailOutbox.COD > 0 then
Asa@39 174 self:Debug(format("MAIL_SUCCESS %d [To: %s] [Subject: %s] [COD: %s]", self.mailOutbox.key, self.mailOutbox.to, self.mailOutbox.subject, self.mailOutbox.COD))
Asa@39 175
Asa@39 176 self.mailOutbox.sent = time()
Asa@39 177 self.db.factionrealm.outbound_cod[self.mailOutbox.key] = self.mailOutbox
Asa@39 178 end
Asa@92 179
Asa@92 180 wipe(attachedItems)
Asa@40 181 self:GenerateBlankOutbox()
Asa@3 182 end
Asa@3 183
Asa@63 184 function ItemAuditor:MAIL_CLOSED()
Asa@23 185 self:Debug("MAIL_CLOSED")
Asa@63 186 ItemAuditor:UnregisterEvent("MAIL_CLOSED")
Asa@7 187 self:MAIL_INBOX_UPDATE()
Asa@3 188 self:UnregisterEvent("MAIL_INBOX_UPDATE")
Asa@3 189 self:RegisterEvent("MAIL_SHOW")
Asa@39 190 self:WatchBags()
Asa@3 191 end
Asa@3 192
Asa@26 193 local storedCountDiff
Asa@63 194 function ItemAuditor:MAIL_INBOX_UPDATE()
Asa@23 195 self:Debug("MAIL_INBOX_UPDATE")
Asa@63 196 local newScan = ItemAuditor:ScanMail()
Asa@3 197 local diff
Asa@39 198
Asa@6 199 for mailType, collection in pairs(self.lastMailScan) do
Asa@7 200 newScan[mailType] = (newScan[mailType] or {})
Asa@26 201 for itemName, data in pairs(collection) do
Asa@26 202 newScan[mailType][itemName] = (newScan[mailType][itemName] or {total=0,count=0})
Asa@26 203 local totalDiff = data.total - newScan[mailType][itemName].total
Asa@26 204 local countDiff = data.count - newScan[mailType][itemName].count
Asa@26 205 --[[
Asa@26 206 In one update the item will be taken and in the following update the invoice
Asa@26 207 will be gone. I need to store the item difference in order ot pass it into
Asa@26 208 SaveValue.
Asa@26 209 ]]
Asa@26 210 if countDiff ~= 0 then
Asa@26 211 storedCountDiff = countDiff
Asa@26 212 end
Asa@26 213
Asa@26 214 if totalDiff ~= 0 then
Asa@39 215 if mailType == "CODPayment" then
Asa@39 216 local trackID
Asa@39 217 trackID, itemName= strsplit("|", itemName, 2)
Asa@39 218 self.db.factionrealm.outbound_cod[tonumber(trackID)] = nil
Asa@39 219 self:Debug("Removing COD Tracker: " .. trackID)
Asa@39 220 end
Asa@26 221 self:SaveValue(itemName, totalDiff, storedCountDiff)
Asa@26 222 storedCountDiff = 0
Asa@6 223 end
Asa@6 224
Asa@3 225 end
Asa@3 226 end
Asa@3 227
Asa@3 228 self.lastMailScan = newScan
Asa@3 229 end
Asa@3 230
Asa@63 231 function ItemAuditor:UNIT_SPELLCAST_START(event, target, spell)
Asa@5 232 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then
Asa@23 233 self:Debug(event .. " " .. spell)
Asa@4 234 self:UnwatchBags()
Asa@4 235 self:UpdateCurrentInventory()
Asa@4 236 self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 237 self:RegisterEvent("LOOT_CLOSED")
Asa@3 238 end
Asa@3 239 end
Asa@3 240
Asa@4 241 --[[
Asa@4 242 The item should be destroyed before this point, so the last inventory check
Asa@4 243 needs to be kept so it can be combined with the up coming loot.
Asa@4 244 ]]
Asa@63 245 function ItemAuditor:LOOT_CLOSED()
Asa@23 246 self:Debug("LOOT_CLOSED")
Asa@4 247 self:UnregisterEvent("LOOT_CLOSED")
Asa@4 248 self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 249 local inventory = self.lastInventory
Asa@4 250 self:WatchBags()
Asa@4 251 self.lastInventory = inventory
Asa@4 252 end
Asa@3 253
Asa@63 254 function ItemAuditor:UNIT_SPELLCAST_INTERRUPTED(event, target, spell)
Asa@5 255 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then
Asa@23 256 self:Debug(event .. " " .. spell)
Asa@4 257 self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 258 self:UnregisterEvent("LOOT_CLOSED")
Asa@4 259 self:WatchBags()
Asa@4 260 end
Asa@4 261 end
Asa@4 262
Asa@63 263 function ItemAuditor:UpdateCurrentInventory()
Asa@4 264 self.lastInventory = self:GetCurrentInventory()
Asa@3 265 end
Asa@3 266
Asa@49 267 local function distributeValue(self, totalValue, targetItems)
Asa@46 268
Asa@46 269 local weights = {}
Asa@46 270 local totalWeight = 0
Asa@46 271 for link, change in pairs(targetItems) do
Asa@46 272 --[[
Asa@46 273 If something has never been seen on the AH, it must not be very valuable.
Asa@46 274 I'm using 1c so it doesn't have much weight and I can't get a devided by zero error.
Asa@46 275 The only time I know that this is a problem is when crafting a BOP item, and it
Asa@46 276 is always crafted 1 at a time, so a weight of 1 will work.
Asa@46 277 ]]
Asa@63 278 local ap = (ItemAuditor:GetAuctionPrice(link) or 1) * change
Asa@46 279 totalWeight = totalWeight + ap
Asa@46 280 weights[link] = ap
Asa@46 281 end
Asa@46 282
Asa@46 283 for link, change in pairs(targetItems) do
Asa@52 284 local value = totalValue * (weights[link]/totalWeight)
Asa@52 285 self:SaveValue(link, value, change)
Asa@46 286 end
Asa@46 287 end
Asa@46 288
Asa@63 289 function ItemAuditor:UpdateAudit()
Asa@23 290 -- self:Debug("UpdateAudit " .. event)
Asa@3 291 local currentInventory = self:GetCurrentInventory()
Asa@63 292 local diff = ItemAuditor:GetInventoryDiff(self.lastInventory, currentInventory)
Asa@3 293
Asa@5 294 local positive, negative = {}, {}
Asa@5 295 local positiveCount, negativeCount = 0, 0
Asa@5 296 for item, count in pairs(diff.items) do
Asa@5 297 if count > 0 then
Asa@5 298 positive[item] = count
Asa@5 299 positiveCount = positiveCount + count
Asa@5 300 elseif count < 0 then
Asa@5 301 negative[item] = count
Asa@5 302 negativeCount = negativeCount + abs(count)
Asa@5 303 end
Asa@5 304 end
Asa@5 305
Asa@23 306 if positiveCount + negativeCount == 0 then
Asa@33 307 --[[
Asa@33 308 Nothing needs to be done, but this will prevent mistakenly attributing
Asa@33 309 the cost of flights to the first item you pick up.
Asa@33 310 ]]
Asa@33 311 elseif diff.money > 0 and self:tcount(positive) > 0 and self:tcount(negative) == 0 then
Asa@15 312 self:Debug("loot")
Asa@20 313 elseif abs(diff.money) > 0 and self:tcount(diff.items) == 1 then
Asa@15 314 self:Debug("purchase or sale")
Asa@3 315
Asa@9 316 for link, count in pairs(diff.items) do
Asa@26 317 self:SaveValue(link, 0 - diff.money, count)
Asa@3 318 end
Asa@23 319 elseif self:tcount(diff.items) > 1 and self:tcount(positive) > 0 and self:tcount(negative) > 0 then
Asa@23 320 -- we must have created/converted something
Asa@23 321 self:Debug("conversion")
Asa@3 322
Asa@23 323 local totalChange = 0
Asa@23 324 for link, change in pairs(negative) do
Asa@23 325 local _, itemCost, count = self:GetItemCost(link, change)
Asa@26 326 self:SaveValue(link, itemCost * change, change)
Asa@10 327
Asa@23 328 totalChange = totalChange + (itemCost * abs(change))
Asa@3 329 end
Asa@91 330 totalChange = totalChange - diff.money
Asa@23 331
Asa@46 332 distributeValue(self, totalChange, positive)
Asa@23 333 else
Asa@23 334 self:Debug("No match in UpdateAudit.")
Asa@3 335 end
Asa@3 336
Asa@3 337 self.lastInventory = currentInventory
Asa@63 338 ItemAuditor:WatchBags()
Asa@3 339 end