annotate Modules/Events.lua @ 77:a8fc802b42ba

Changed the QuickAuctions decider to consider the number already owned and only calculate based on what needs to be crated. Fixed the QuickAuctions decider to return the number of items to be created instead of the number of times to create. This makes a difference with things like Runescroll of Fortitude where 5 are created at once.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Sun, 01 Aug 2010 08:42:29 -0700
parents e7d287cc3b02
children 64166ba5209a
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@63 4 function ItemAuditor:OnEnable()
Asa@3 5 self:RegisterEvent("MAIL_SHOW")
Asa@4 6 self:RegisterEvent("UNIT_SPELLCAST_START")
Asa@63 7 ItemAuditor:UpdateCurrentInventory()
Asa@3 8 self:WatchBags()
Asa@9 9
Asa@63 10 self:SetEnabled(nil, self.db.profile.ItemAuditor_enabled)
Asa@38 11 end
Asa@38 12
Asa@63 13 function ItemAuditor:OnDisable()
Asa@38 14 self:UnwatchBags()
Asa@38 15 self:UnregisterAllEvents()
Asa@63 16 ItemAuditor:HideAllFrames()
Asa@3 17 end
Asa@3 18
Asa@63 19 function ItemAuditor:MAIL_SHOW()
Asa@3 20 self:Debug("MAIL_SHOW")
Asa@39 21 self:UnwatchBags()
Asa@63 22 ItemAuditor: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@63 34 function ItemAuditor: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 for link, data in pairs(attachedItems) do
Asa@53 92 data.price = 30 * data.stacks
Asa@40 93 end
Asa@40 94
Asa@42 95 if self.mailOutbox.COD > 0 and skipCODTracking then
Asa@42 96
Asa@42 97 elseif self.mailOutbox.COD > 0 then
Asa@40 98 if self:tcount(attachedItems) > 1 then
Asa@39 99 self:GenerateBlankOutbox()
Asa@42 100 local vararg = ...
Asa@42 101 StaticPopupDialogs["ItemAuditor_Send_COD_without_tracking_number"].OnAccept = function()
Asa@42 102 skipCODTracking = true
Asa@42 103 SendMail(recipient, subject, body, vararg)
Asa@42 104 skipCODTracking = false
Asa@42 105 end
Asa@42 106 StaticPopup_Show ("ItemAuditor_Send_COD_without_tracking_number");
Asa@39 107 return
Asa@39 108 end
Asa@40 109 self:Debug("COD mail")
Asa@39 110
Asa@40 111 subject = format("[IA: %s] %s", self.mailOutbox.key, subject)
Asa@40 112 self.mailOutbox.subject = subject
Asa@40 113 self.mailOutbox.to = recipient
Asa@40 114
Asa@40 115 -- At this point we know there is only one item
Asa@40 116 for link, data in pairs(attachedItems) do
Asa@40 117 self.mailOutbox.link = link
Asa@40 118 self.mailOutbox.count = data.count
Asa@40 119 end
Asa@40 120 else
Asa@40 121 self:Debug("Non-COD mail")
Asa@39 122 end
Asa@40 123
Asa@39 124 return Orig_SendMail(recipient, subject, body, ...)
Asa@39 125 end
Asa@39 126
Asa@63 127 function ItemAuditor:MAIL_SUCCESS(event)
Asa@42 128 skipCODTracking = false
Asa@40 129 for link, data in pairs(attachedItems) do
Asa@40 130 self:SaveValue(link, data.price, data.count)
Asa@40 131 end
Asa@39 132 if self.mailOutbox.COD > 0 then
Asa@39 133 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 134
Asa@39 135 self.mailOutbox.sent = time()
Asa@39 136 self.db.factionrealm.outbound_cod[self.mailOutbox.key] = self.mailOutbox
Asa@39 137 end
Asa@39 138
Asa@40 139
Asa@40 140 self:GenerateBlankOutbox()
Asa@3 141 end
Asa@3 142
Asa@63 143 function ItemAuditor:MAIL_CLOSED()
Asa@23 144 self:Debug("MAIL_CLOSED")
Asa@63 145 ItemAuditor:UnregisterEvent("MAIL_CLOSED")
Asa@7 146 self:MAIL_INBOX_UPDATE()
Asa@3 147 self:UnregisterEvent("MAIL_INBOX_UPDATE")
Asa@3 148 self:RegisterEvent("MAIL_SHOW")
Asa@39 149 self:WatchBags()
Asa@3 150 end
Asa@3 151
Asa@26 152 local storedCountDiff
Asa@63 153 function ItemAuditor:MAIL_INBOX_UPDATE()
Asa@23 154 self:Debug("MAIL_INBOX_UPDATE")
Asa@63 155 local newScan = ItemAuditor:ScanMail()
Asa@3 156 local diff
Asa@39 157
Asa@6 158 for mailType, collection in pairs(self.lastMailScan) do
Asa@7 159 newScan[mailType] = (newScan[mailType] or {})
Asa@26 160 for itemName, data in pairs(collection) do
Asa@26 161 newScan[mailType][itemName] = (newScan[mailType][itemName] or {total=0,count=0})
Asa@26 162 local totalDiff = data.total - newScan[mailType][itemName].total
Asa@26 163 local countDiff = data.count - newScan[mailType][itemName].count
Asa@26 164 --[[
Asa@26 165 In one update the item will be taken and in the following update the invoice
Asa@26 166 will be gone. I need to store the item difference in order ot pass it into
Asa@26 167 SaveValue.
Asa@26 168 ]]
Asa@26 169 if countDiff ~= 0 then
Asa@26 170 storedCountDiff = countDiff
Asa@26 171 end
Asa@26 172
Asa@26 173 if totalDiff ~= 0 then
Asa@39 174 if mailType == "CODPayment" then
Asa@39 175 local trackID
Asa@39 176 trackID, itemName= strsplit("|", itemName, 2)
Asa@39 177 self.db.factionrealm.outbound_cod[tonumber(trackID)] = nil
Asa@39 178 self:Debug("Removing COD Tracker: " .. trackID)
Asa@39 179 end
Asa@26 180 self:SaveValue(itemName, totalDiff, storedCountDiff)
Asa@26 181 storedCountDiff = 0
Asa@6 182 end
Asa@6 183
Asa@3 184 end
Asa@3 185 end
Asa@3 186
Asa@3 187 self.lastMailScan = newScan
Asa@3 188 end
Asa@3 189
Asa@63 190 function ItemAuditor:UNIT_SPELLCAST_START(event, target, spell)
Asa@5 191 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then
Asa@23 192 self:Debug(event .. " " .. spell)
Asa@4 193 self:UnwatchBags()
Asa@4 194 self:UpdateCurrentInventory()
Asa@4 195 self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 196 self:RegisterEvent("LOOT_CLOSED")
Asa@3 197 end
Asa@3 198 end
Asa@3 199
Asa@4 200 --[[
Asa@4 201 The item should be destroyed before this point, so the last inventory check
Asa@4 202 needs to be kept so it can be combined with the up coming loot.
Asa@4 203 ]]
Asa@63 204 function ItemAuditor:LOOT_CLOSED()
Asa@23 205 self:Debug("LOOT_CLOSED")
Asa@4 206 self:UnregisterEvent("LOOT_CLOSED")
Asa@4 207 self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 208 local inventory = self.lastInventory
Asa@4 209 self:WatchBags()
Asa@4 210 self.lastInventory = inventory
Asa@4 211 end
Asa@3 212
Asa@63 213 function ItemAuditor:UNIT_SPELLCAST_INTERRUPTED(event, target, spell)
Asa@5 214 if target == "player" and spell == "Milling" or spell == "Prospecting" or spell == "Disenchanting" then
Asa@23 215 self:Debug(event .. " " .. spell)
Asa@4 216 self:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED")
Asa@4 217 self:UnregisterEvent("LOOT_CLOSED")
Asa@4 218 self:WatchBags()
Asa@4 219 end
Asa@4 220 end
Asa@4 221
Asa@63 222 function ItemAuditor:UpdateCurrentInventory()
Asa@4 223 self.lastInventory = self:GetCurrentInventory()
Asa@3 224 end
Asa@3 225
Asa@49 226 local function distributeValue(self, totalValue, targetItems)
Asa@46 227
Asa@46 228 local weights = {}
Asa@46 229 local totalWeight = 0
Asa@46 230 for link, change in pairs(targetItems) do
Asa@46 231 --[[
Asa@46 232 If something has never been seen on the AH, it must not be very valuable.
Asa@46 233 I'm using 1c so it doesn't have much weight and I can't get a devided by zero error.
Asa@46 234 The only time I know that this is a problem is when crafting a BOP item, and it
Asa@46 235 is always crafted 1 at a time, so a weight of 1 will work.
Asa@46 236 ]]
Asa@63 237 local ap = (ItemAuditor:GetAuctionPrice(link) or 1) * change
Asa@46 238 totalWeight = totalWeight + ap
Asa@46 239 weights[link] = ap
Asa@46 240 end
Asa@46 241
Asa@46 242 for link, change in pairs(targetItems) do
Asa@52 243 local value = totalValue * (weights[link]/totalWeight)
Asa@52 244 self:SaveValue(link, value, change)
Asa@46 245 end
Asa@46 246 end
Asa@46 247
Asa@63 248 function ItemAuditor:UpdateAudit()
Asa@23 249 -- self:Debug("UpdateAudit " .. event)
Asa@3 250 local currentInventory = self:GetCurrentInventory()
Asa@63 251 local diff = ItemAuditor:GetInventoryDiff(self.lastInventory, currentInventory)
Asa@3 252
Asa@5 253 local positive, negative = {}, {}
Asa@5 254 local positiveCount, negativeCount = 0, 0
Asa@5 255 for item, count in pairs(diff.items) do
Asa@5 256 if count > 0 then
Asa@5 257 positive[item] = count
Asa@5 258 positiveCount = positiveCount + count
Asa@5 259 elseif count < 0 then
Asa@5 260 negative[item] = count
Asa@5 261 negativeCount = negativeCount + abs(count)
Asa@5 262 end
Asa@5 263 end
Asa@5 264
Asa@23 265 if positiveCount + negativeCount == 0 then
Asa@33 266 --[[
Asa@33 267 Nothing needs to be done, but this will prevent mistakenly attributing
Asa@33 268 the cost of flights to the first item you pick up.
Asa@33 269 ]]
Asa@33 270 elseif diff.money > 0 and self:tcount(positive) > 0 and self:tcount(negative) == 0 then
Asa@15 271 self:Debug("loot")
Asa@20 272 elseif abs(diff.money) > 0 and self:tcount(diff.items) == 1 then
Asa@15 273 self:Debug("purchase or sale")
Asa@3 274
Asa@9 275 for link, count in pairs(diff.items) do
Asa@26 276 self:SaveValue(link, 0 - diff.money, count)
Asa@3 277 end
Asa@23 278 elseif self:tcount(diff.items) > 1 and self:tcount(positive) > 0 and self:tcount(negative) > 0 then
Asa@23 279 -- we must have created/converted something
Asa@23 280 self:Debug("conversion")
Asa@3 281
Asa@23 282 local totalChange = 0
Asa@23 283 for link, change in pairs(negative) do
Asa@23 284 local _, itemCost, count = self:GetItemCost(link, change)
Asa@26 285 self:SaveValue(link, itemCost * change, change)
Asa@10 286
Asa@23 287 totalChange = totalChange + (itemCost * abs(change))
Asa@3 288 end
Asa@23 289
Asa@46 290 distributeValue(self, totalChange, positive)
Asa@23 291 else
Asa@23 292 self:Debug("No match in UpdateAudit.")
Asa@3 293 end
Asa@3 294
Asa@3 295 self.lastInventory = currentInventory
Asa@63 296 ItemAuditor:WatchBags()
Asa@3 297 end