annotate Modules/Events.lua @ 49:9ff6a3b02332 ticket7

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