Mercurial > wow > wowdb-profiler
comparison Main.lua @ 1:d9375a473042
Handle looting items and money from NPCs. Beginning of handling for looting from objects and gathering (mining, herbalism) from NPCs among other spell-related obtaining methods.
| author | James D. Callahan III <jcallahan@curse.com> |
|---|---|
| date | Fri, 27 Apr 2012 03:49:03 -0500 |
| parents | 2e4d83460542 |
| children | d563ea0ec911 |
comparison
equal
deleted
inserted
replaced
| 0:2e4d83460542 | 1:d9375a473042 |
|---|---|
| 2 -- Upvalued Lua API. | 2 -- Upvalued Lua API. |
| 3 ----------------------------------------------------------------------- | 3 ----------------------------------------------------------------------- |
| 4 local _G = getfenv(0) | 4 local _G = getfenv(0) |
| 5 | 5 |
| 6 local pairs = _G.pairs | 6 local pairs = _G.pairs |
| 7 local tonumber = _G.tonumber | |
| 8 | |
| 9 local bit = _G.bit | |
| 10 local math = _G.math | |
| 11 local table = _G.table | |
| 12 | |
| 7 | 13 |
| 8 ----------------------------------------------------------------------- | 14 ----------------------------------------------------------------------- |
| 9 -- AddOn namespace. | 15 -- AddOn namespace. |
| 10 ----------------------------------------------------------------------- | 16 ----------------------------------------------------------------------- |
| 11 local ADDON_NAME, private = ... | 17 local ADDON_NAME, private = ... |
| 12 | 18 |
| 13 local LibStub = _G.LibStub | 19 local LibStub = _G.LibStub |
| 14 local WDP = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceEvent-3.0", "AceTimer-3.0") | 20 local WDP = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceEvent-3.0", "AceTimer-3.0") |
| 15 | 21 |
| 16 ----------------------------------------------------------------------- | |
| 17 -- Function declarations. | |
| 18 ----------------------------------------------------------------------- | |
| 19 local HandleSpellFailure | |
| 20 local HandleZoneChange | |
| 21 | 22 |
| 22 ----------------------------------------------------------------------- | 23 ----------------------------------------------------------------------- |
| 23 -- Local constants. | 24 -- Local constants. |
| 24 ----------------------------------------------------------------------- | 25 ----------------------------------------------------------------------- |
| 25 local DATABASE_DEFAULTS = { | 26 local DATABASE_DEFAULTS = { |
| 30 quests = {}, | 31 quests = {}, |
| 31 } | 32 } |
| 32 } | 33 } |
| 33 | 34 |
| 34 | 35 |
| 35 local EVENT_MAPPING = {-- ARTIFACT_COMPLETE = true, | 36 local EVENT_MAPPING = { |
| 37 -- ARTIFACT_COMPLETE = true, | |
| 36 -- ARTIFACT_HISTORY_READY = true, | 38 -- ARTIFACT_HISTORY_READY = true, |
| 37 -- AUCTION_HOUSE_SHOW = true, | 39 -- AUCTION_HOUSE_SHOW = true, |
| 38 -- BANKFRAME_OPENED = true, | 40 -- BANKFRAME_OPENED = true, |
| 39 -- BATTLEFIELDS_SHOW = true, | 41 -- BATTLEFIELDS_SHOW = true, |
| 40 -- CHAT_MSG_ADDON = true, | 42 -- CHAT_MSG_ADDON = true, |
| 52 -- GOSSIP_ENTER_CODE = true, | 54 -- GOSSIP_ENTER_CODE = true, |
| 53 -- GOSSIP_SHOW = true, | 55 -- GOSSIP_SHOW = true, |
| 54 -- ITEM_TEXT_BEGIN = true, | 56 -- ITEM_TEXT_BEGIN = true, |
| 55 -- LOCALPLAYER_PET_RENAMED = true, | 57 -- LOCALPLAYER_PET_RENAMED = true, |
| 56 -- LOOT_CLOSED = true, | 58 -- LOOT_CLOSED = true, |
| 57 -- LOOT_OPENED = true, | 59 LOOT_OPENED = true, |
| 58 -- MAIL_SHOW = true, | 60 -- MAIL_SHOW = true, |
| 59 -- MERCHANT_SHOW = true, | 61 -- MERCHANT_SHOW = true, |
| 60 -- MERCHANT_UPDATE = true, | 62 -- MERCHANT_UPDATE = true, |
| 61 -- OPEN_TABARD_FRAME = true, | 63 -- OPEN_TABARD_FRAME = true, |
| 62 -- PET_BAR_UPDATE = true, | 64 -- PET_BAR_UPDATE = true, |
| 73 -- TAXIMAP_OPENED = true, | 75 -- TAXIMAP_OPENED = true, |
| 74 -- TRADE_SKILL_SHOW = true, | 76 -- TRADE_SKILL_SHOW = true, |
| 75 -- TRADE_SKILL_UPDATE = true, | 77 -- TRADE_SKILL_UPDATE = true, |
| 76 -- TRAINER_SHOW = true, | 78 -- TRAINER_SHOW = true, |
| 77 -- UNIT_QUEST_LOG_CHANGED = true, | 79 -- UNIT_QUEST_LOG_CHANGED = true, |
| 78 -- UNIT_SPELLCAST_FAILED = HandleSpellFailure, | 80 UNIT_SPELLCAST_FAILED = "HandleSpellFailure", |
| 79 -- UNIT_SPELLCAST_FAILED_QUIET = HandleSpellFailure, | 81 UNIT_SPELLCAST_FAILED_QUIET = "HandleSpellFailure", |
| 80 -- UNIT_SPELLCAST_INTERRUPTED = HandleSpellFailure, | 82 UNIT_SPELLCAST_INTERRUPTED = "HandleSpellFailure", |
| 81 -- UNIT_SPELLCAST_SENT = true, | 83 UNIT_SPELLCAST_SENT = true, |
| 82 -- UNIT_SPELLCAST_SUCCEEDED = true, | 84 UNIT_SPELLCAST_SUCCEEDED = true, |
| 83 -- ZONE_CHANGED = HandleZoneChange, | 85 -- ZONE_CHANGED = HandleZoneChange, |
| 84 -- ZONE_CHANGED_NEW_AREA = HandleZoneChange, | 86 -- ZONE_CHANGED_NEW_AREA = HandleZoneChange, |
| 85 } | 87 } |
| 86 | 88 |
| 89 local AF = private.ACTION_TYPE_FLAGS | |
| 87 | 90 |
| 88 ----------------------------------------------------------------------- | 91 ----------------------------------------------------------------------- |
| 89 -- Local variables. | 92 -- Local variables. |
| 90 ----------------------------------------------------------------------- | 93 ----------------------------------------------------------------------- |
| 91 local db | 94 local db |
| 92 local durability_timer_handle | 95 local durability_timer_handle |
| 93 | 96 local action_data = {} |
| 97 | |
| 98 do | |
| 99 local UNIT_TYPE_BITMASK = 0x007 | |
| 100 | |
| 101 function WDP:ParseGUID(guid) | |
| 102 local types = private.UNIT_TYPES | |
| 103 local unit_type = _G.bit.band(tonumber(guid:sub(1, 5)), UNIT_TYPE_BITMASK) | |
| 104 | |
| 105 if unit_type ~= types.PLAYER or unit_type ~= types.OBJECT or unit_type ~= types.PET then | |
| 106 return unit_type, tonumber(guid:sub(-12, -9), 16) | |
| 107 end | |
| 108 | |
| 109 return unit_type | |
| 110 end | |
| 111 end -- do-block | |
| 112 | |
| 113 | |
| 114 ----------------------------------------------------------------------- | |
| 115 -- Helper Functions. | |
| 116 ----------------------------------------------------------------------- | |
| 117 local function CurrentLocationData() | |
| 118 local map_level = _G.GetCurrentMapDungeonLevel() or 0 | |
| 119 local x, y = _G.GetPlayerMapPosition("player") | |
| 120 | |
| 121 x = x or 0 | |
| 122 y = y or 0 | |
| 123 | |
| 124 if x == 0 and y == 0 then | |
| 125 for level_index = 1, _G.GetNumDungeonMapLevels() do | |
| 126 _G.SetDungeonMapLevel(level_index) | |
| 127 x, y = _G.GetPlayerMapPosition("player") | |
| 128 | |
| 129 if x and y and (x > 0 or y > 0) then | |
| 130 _G.SetDungeonMapLevel(map_level) | |
| 131 map_level = level_index | |
| 132 break | |
| 133 end | |
| 134 end | |
| 135 end | |
| 136 | |
| 137 if _G.DungeonUsesTerrainMap() then | |
| 138 map_level = map_level - 1 | |
| 139 end | |
| 140 | |
| 141 return _G.GetRealZoneText(), math.floor(x * 1000 + 0.5), math.floor(y * 1000 + 0.5), map_level or 0 | |
| 142 end | |
| 143 | |
| 144 | |
| 145 local function ItemLinkToID(item_link) | |
| 146 if not item_link then | |
| 147 return | |
| 148 end | |
| 149 local id = item_link:match("item:(%d+)") | |
| 150 return id and tonumber(id) or nil | |
| 151 end | |
| 94 | 152 |
| 95 ----------------------------------------------------------------------- | 153 ----------------------------------------------------------------------- |
| 96 -- Methods. | 154 -- Methods. |
| 97 ----------------------------------------------------------------------- | 155 ----------------------------------------------------------------------- |
| 98 function WDP:OnInitialize() | 156 function WDP:OnInitialize() |
| 100 end | 158 end |
| 101 | 159 |
| 102 | 160 |
| 103 function WDP:OnEnable() | 161 function WDP:OnEnable() |
| 104 for event_name, mapping in pairs(EVENT_MAPPING) do | 162 for event_name, mapping in pairs(EVENT_MAPPING) do |
| 105 self:RegisterEvent(event_name, (type(mapping) ~= "boolean") and mapping or nil) | 163 self:RegisterEvent(event_name, (_G.type(mapping) ~= "boolean") and mapping or nil) |
| 106 end | 164 end |
| 107 durability_timer_handle = self:ScheduleRepeatingTimer("ProcessDurability", 30) | 165 durability_timer_handle = self:ScheduleRepeatingTimer("ProcessDurability", 30) |
| 108 end | 166 end |
| 109 | 167 |
| 110 | 168 |
| 120 end | 178 end |
| 121 | 179 |
| 122 | 180 |
| 123 function WDP:ProcessDurability() | 181 function WDP:ProcessDurability() |
| 124 for slot_index = 0, _G.INVSLOT_LAST_EQUIPPED do | 182 for slot_index = 0, _G.INVSLOT_LAST_EQUIPPED do |
| 125 local item_id = _G.GetInventoryItemID("player", slot_index); | 183 local item_id = _G.GetInventoryItemID("player", slot_index) |
| 126 | 184 |
| 127 if item_id and item_id > 0 then | 185 if item_id and item_id > 0 then |
| 128 local _, max_durability = _G.GetInventoryItemDurability(slot_index); | 186 local _, max_durability = _G.GetInventoryItemDurability(slot_index) |
| 129 RecordDurability(item_id, max_durability) | 187 RecordDurability(item_id, max_durability) |
| 130 end | 188 end |
| 131 end | 189 end |
| 132 | 190 |
| 133 for bag_index = 0, _G.NUM_BAG_SLOTS do | 191 for bag_index = 0, _G.NUM_BAG_SLOTS do |
| 134 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do | 192 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do |
| 135 local item_id = _G.GetContainerItemID(bag_index, slot_index); | 193 local item_id = _G.GetContainerItemID(bag_index, slot_index) |
| 136 | 194 |
| 137 if item_id and item_id > 0 then | 195 if item_id and item_id > 0 then |
| 138 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index); | 196 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index) |
| 139 RecordDurability(item_id, max_durability) | 197 RecordDurability(item_id, max_durability) |
| 140 end | 198 end |
| 141 end | 199 end |
| 142 end | 200 end |
| 143 end | 201 end |
| 144 | 202 |
| 145 | 203 |
| 146 ----------------------------------------------------------------------- | 204 ----------------------------------------------------------------------- |
| 147 -- Event handlers. | 205 -- Event handlers. |
| 148 ----------------------------------------------------------------------- | 206 ----------------------------------------------------------------------- |
| 149 function WDP:AUCTION_HOUSE_SHOW() | 207 function WDP:CHAT_MSG_SYSTEM(event_name, message, sender_name, language) |
| 150 end | 208 end |
| 151 | 209 |
| 152 | 210 |
| 153 function WDP:CHAT_MSG_MONSTER_EMOTE() | 211 local re_gold = _G.GOLD_AMOUNT:gsub("%%d", "(%%d+)") |
| 154 end | 212 local re_silver = _G.SILVER_AMOUNT:gsub("%%d", "(%%d+)") |
| 155 | 213 local re_copper = _G.COPPER_AMOUNT:gsub("%%d", "(%%d+)") |
| 156 | 214 |
| 157 function WDP:CHAT_MSG_MONSTER_SAY() | 215 |
| 158 end | 216 local function _moneyMatch(money, re) |
| 159 | 217 return money:match(re) or 0 |
| 160 | 218 end |
| 161 function WDP:CHAT_MSG_MONSTER_WHISPER() | 219 |
| 162 end | 220 |
| 163 | 221 local function _toCopper(money) |
| 164 | 222 if not money then |
| 165 function WDP:CHAT_MSG_MONSTER_YELL() | 223 return 0 |
| 166 end | 224 end |
| 167 | 225 |
| 168 | 226 return _moneyMatch(money, re_gold) * 10000 + _moneyMatch(money, re_silver) * 100 + _moneyMatch(money, re_copper) |
| 169 function WDP:CHAT_MSG_SYSTEM(event, message, sender_name, language) | 227 end |
| 170 end | 228 |
| 171 | 229 |
| 172 | 230 local LOOT_VERIFY_FUNCS = { |
| 173 function WDP:GOSSIP_SHOW() | 231 [AF.NPC] = function() |
| 174 end | 232 local fishing_loot = _G.IsFishingLoot() |
| 175 | 233 |
| 176 | 234 if not fishing_loot and _G.UnitExists("target") and not _G.UnitIsFriend("player", "target") and _G.UnitIsDead("target") then |
| 177 function WDP:ADDON_ALIVE() | 235 if _G.UnitIsPlayer("target") or _G.UnitPlayerControlled("target") then |
| 178 end | 236 return false |
| 179 | 237 end |
| 180 | 238 local unit_type, id_num = WDP:ParseGUID(_G.UnitGUID("target")) |
| 181 function WDP:PLAYER_LOGIN() | 239 action_data.id_num = id_num |
| 182 end | 240 end |
| 183 | 241 return true |
| 184 | 242 end, |
| 185 function WDP:PLAYER_LOGOUT() | 243 } |
| 186 end | 244 |
| 187 | 245 local LOOT_UPDATE_FUNCS = { |
| 188 | 246 [AF.NPC] = function() |
| 189 function WDP:PLAYER_TARGET_CHANGED() | 247 local npc = db.npcs[action_data.id_num] |
| 190 end | 248 |
| 191 | 249 if not npc then |
| 192 | 250 db.npcs[action_data.id_num] = {} |
| 193 function WDP:QUEST_LOG_UPDATE() | 251 npc = db.npcs[action_data.id_num] |
| 194 end | 252 end |
| 195 | 253 npc.drops = npc.drops or {} |
| 196 | 254 |
| 197 function WDP:TRADE_SKILL_UPDATE() | 255 for index = 1, #action_data.drops do |
| 198 end | 256 table.insert(npc.drops, action_data.drops[index]) |
| 257 end | |
| 258 end, | |
| 259 } | |
| 260 | |
| 261 | |
| 262 function WDP:LOOT_OPENED() | |
| 263 if not action_data.type then | |
| 264 action_data.type = AF.NPC | |
| 265 end | |
| 266 local verify_func = LOOT_VERIFY_FUNCS[action_data.type] | |
| 267 local update_func = LOOT_UPDATE_FUNCS[action_data.type] | |
| 268 | |
| 269 if not verify_func or not update_func or not verify_func() then | |
| 270 return | |
| 271 end | |
| 272 | |
| 273 local loot_registry = {} | |
| 274 action_data.drops = {} | |
| 275 | |
| 276 for loot_slot = 1, _G.GetNumLootItems() do | |
| 277 local texture, item, quantity, quality, locked = _G.GetLootSlotInfo(loot_slot) | |
| 278 | |
| 279 if _G.LootSlotIsItem(loot_slot) then | |
| 280 local item_id = ItemLinkToID(_G.GetLootSlotLink(loot_slot)) | |
| 281 loot_registry[item_id] = (loot_registry[item_id]) or 0 + quantity | |
| 282 elseif _G.LootSlotIsCoin(loot_slot) then | |
| 283 table.insert(action_data.drops, ("money:%d"):format(_toCopper(item))) | |
| 284 elseif _G.LootSlotIsCurrency(loot_slot) then | |
| 285 end | |
| 286 end | |
| 287 | |
| 288 for item_id, quantity in pairs(loot_registry) do | |
| 289 table.insert(action_data.drops, ("%d:%d"):format(item_id, quantity)) | |
| 290 end | |
| 291 update_func() | |
| 292 end | |
| 293 | |
| 294 | |
| 295 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line) | |
| 296 if private.tracked_line or unit_id ~= "player" then | |
| 297 return | |
| 298 end | |
| 299 local spell_label = private.SPELL_LABELS_BY_NAME[spell_name] | |
| 300 | |
| 301 if not spell_label then | |
| 302 return | |
| 303 end | |
| 304 action_data.type = nil -- This will be set as appropriate below | |
| 305 | |
| 306 local tt_item_name, tt_item_link = _G.GameTooltip:GetItem() | |
| 307 local tt_unit_name, tt_unit_id = _G.GameTooltip:GetUnit() | |
| 308 | |
| 309 if not tt_unit_name and _G.UnitName("target") == target_name then | |
| 310 tt_unit_name = target_name | |
| 311 tt_unit_id = "target" | |
| 312 end | |
| 313 local spell_flags = private.SPELL_FLAGS_BY_LABEL[spell_label] | |
| 314 | |
| 315 if not tt_item_name and not tt_unit_name then | |
| 316 if target_name == "" then | |
| 317 return | |
| 318 end | |
| 319 | |
| 320 local zone_name, x, y, map_level = CurrentLocationData() | |
| 321 | |
| 322 if bit.band(spell_flags, AF.OBJECT) == AF.OBJECT then | |
| 323 action_data.map_level = map_level | |
| 324 action_data.name = target_name | |
| 325 action_data.type = AF.OBJECT | |
| 326 action_data.x = x | |
| 327 action_data.y = y | |
| 328 action_data.zone = zone_name | |
| 329 print("Found spell flagged for OBJECT") | |
| 330 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then | |
| 331 print("Found spell flagged for ZONE") | |
| 332 end | |
| 333 elseif tt_unit_name and not tt_item_name then | |
| 334 if bit.band(spell_flags, AF.NPC) == AF.NPC then | |
| 335 print("Found spell flagged for NPC") | |
| 336 end | |
| 337 elseif bit.band(spell_flags, AF.ITEM) == AF.ITEM then | |
| 338 print("Found spell flagged for ITEM") | |
| 339 else | |
| 340 print(("%s: We have an issue with types and flags."), event_name) | |
| 341 end | |
| 342 | |
| 343 print(("%s: '%s', '%s', '%s', '%s', '%s'"):format(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)) | |
| 344 private.tracked_line = spell_line | |
| 345 end | |
| 346 | |
| 347 | |
| 348 function WDP:UNIT_SPELLCAST_SUCCEEDED(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id) | |
| 349 if unit_id ~= "player" then | |
| 350 return | |
| 351 end | |
| 352 | |
| 353 if action_data.type == AF.OBJECT then | |
| 354 end | |
| 355 | |
| 356 if private.SPELL_LABELS_BY_NAME[spell_name] then | |
| 357 print(("%s: '%s', '%s', '%s', '%s', '%s'"):format(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)) | |
| 358 end | |
| 359 private.tracked_line = nil | |
| 360 end | |
| 361 | |
| 362 function WDP:HandleSpellFailure(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id) | |
| 363 if unit_id ~= "player" then | |
| 364 return | |
| 365 end | |
| 366 | |
| 367 if private.tracked_line == spell_line then | |
| 368 private.tracked_line = nil | |
| 369 end | |
| 370 end |
