jcallahan@246
|
1 -- LUA API ------------------------------------------------------------
|
jcallahan@246
|
2
|
jcallahan@0
|
3 local _G = getfenv(0)
|
jcallahan@0
|
4
|
jcallahan@0
|
5 local pairs = _G.pairs
|
jcallahan@312
|
6 local tostring = _G.tostring
|
jcallahan@1
|
7 local tonumber = _G.tonumber
|
jcallahan@1
|
8
|
jcallahan@1
|
9 local bit = _G.bit
|
jcallahan@1
|
10 local math = _G.math
|
jcallahan@1
|
11 local table = _G.table
|
jcallahan@1
|
12
|
jcallahan@334
|
13 local next = _G.next
|
jcallahan@78
|
14 local select = _G.select
|
mmosimca@485
|
15 local type = _G.type
|
jcallahan@306
|
16 local unpack = _G.unpack
|
jcallahan@78
|
17
|
MMOSimca@383
|
18 local C_Timer = _G.C_Timer
|
MMOSimca@581
|
19 local C_Spell = _G.C_Spell
|
mmosimca@496
|
20 local GetCurrencyInfo = _G.GetCurrencyInfo
|
MMOSimca@383
|
21
|
MMOSimca@583
|
22 local ICL = InCombatLockdown
|
MMOSimca@583
|
23 local III = IsInInstance
|
MMOSimca@583
|
24
|
jcallahan@0
|
25
|
jcallahan@246
|
26 -- ADDON NAMESPACE ----------------------------------------------------
|
jcallahan@246
|
27
|
jcallahan@0
|
28 local ADDON_NAME, private = ...
|
jcallahan@0
|
29
|
jcallahan@0
|
30 local LibStub = _G.LibStub
|
MMOSimca@383
|
31 local WDP = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceConsole-3.0", "AceEvent-3.0")
|
jcallahan@0
|
32
|
jcallahan@48
|
33 local deformat = LibStub("LibDeformat-3.0")
|
atcaleb@558
|
34 local HereBeDragons = LibStub("HereBeDragons-2.0")
|
jcallahan@48
|
35
|
jcallahan@4
|
36 local DatamineTT = _G.CreateFrame("GameTooltip", "WDPDatamineTT", _G.UIParent, "GameTooltipTemplate")
|
jcallahan@5
|
37 DatamineTT:SetOwner(_G.WorldFrame, "ANCHOR_NONE")
|
jcallahan@5
|
38
|
jcallahan@0
|
39
|
atcaleb@566
|
40 -- SIMPLE CONSTANTS ----------------------------------------------------------
|
jcallahan@246
|
41
|
jcallahan@246
|
42 local AF = private.ACTION_TYPE_FLAGS
|
jcallahan@246
|
43 local CLIENT_LOCALE = _G.GetLocale()
|
atcaleb@565
|
44 local DB_VERSION = 19
|
MMOSimca@346
|
45 local DEBUGGING = false
|
jcallahan@156
|
46 local EVENT_DEBUG = false
|
jcallahan@322
|
47
|
mmosimca@485
|
48 -- Timer durations in seconds
|
mmosimca@485
|
49 local DELAY_PROCESS_ITEMS = 30
|
atcaleb@566
|
50 local DELAY_PROCESS_WORLD_QUESTS = 90
|
mmosimca@485
|
51 local DELAY_UPDATE_TARGET_LOCATION = 0.5
|
mmosimca@485
|
52
|
MMOSimca@405
|
53 local ITEM_ID_TIMBER = 114781
|
MMOSimca@405
|
54
|
MMOSimca@581
|
55 local ENUM_LOOTSLOTTYPE_CURRENCY = _G.Enum.LootSlotType.Currency
|
MMOSimca@581
|
56 local ENUM_LOOTSLOTTYPE_ITEM = _G.Enum.LootSlotType.Item
|
MMOSimca@581
|
57 local ENUM_LOOTSLOTTYPE_MONEY = _G.Enum.LootSlotType.Money
|
mmosimca@520
|
58
|
MMOSimca@539
|
59 --local LOOT_SOURCE_ID_UNKNOWN = 1 -- Technically unused right now, but has future use potential
|
MMOSimca@539
|
60 --local LOOT_SOURCE_ID_REDUNDANT = 3 -- Technically unused right now, but has future use potential
|
MMOSimca@422
|
61 local LOOT_SOURCE_ID_GARRISON_CACHE = 10
|
MMOSimca@422
|
62
|
jcallahan@246
|
63 local OBJECT_ID_ANVIL = 192628
|
jcallahan@322
|
64 local OBJECT_ID_FISHING_BOBBER = 35591
|
jcallahan@246
|
65 local OBJECT_ID_FORGE = 1685
|
jcallahan@322
|
66
|
MMOSimca@454
|
67 local PLAYER_CLASS, PLAYER_CLASS_ID = _G.select(2, _G.UnitClass("player"))
|
jcallahan@246
|
68 local PLAYER_FACTION = _G.UnitFactionGroup("player")
|
jcallahan@300
|
69 local PLAYER_GUID
|
mmosimca@485
|
70 local PLAYER_LEVEL = _G.UnitLevel("player")
|
jcallahan@246
|
71 local PLAYER_NAME = _G.UnitName("player")
|
jcallahan@246
|
72 local PLAYER_RACE = _G.select(2, _G.UnitRace("player"))
|
jcallahan@246
|
73
|
mmosimca@520
|
74 local SPELL_ID_UPDATE_INTERACTIONS = 161006
|
MMOSimca@377
|
75
|
atcaleb@566
|
76 local UI_MAP_COSMIC = 946
|
atcaleb@566
|
77
|
jcallahan@246
|
78 local ALLOWED_LOCALES = {
|
jcallahan@246
|
79 enUS = true,
|
jcallahan@246
|
80 enGB = true,
|
MMOSimca@336
|
81 enTW = true,
|
MMOSimca@336
|
82 enCN = true,
|
jcallahan@246
|
83 }
|
jcallahan@157
|
84
|
jcallahan@0
|
85 local DATABASE_DEFAULTS = {
|
jcallahan@128
|
86 char = {},
|
jcallahan@0
|
87 global = {
|
jcallahan@270
|
88 config = {
|
jcallahan@270
|
89 minimap_icon = {
|
jcallahan@270
|
90 hide = true,
|
jcallahan@270
|
91 },
|
jcallahan@270
|
92 },
|
jcallahan@0
|
93 items = {},
|
jcallahan@0
|
94 npcs = {},
|
jcallahan@0
|
95 objects = {},
|
jcallahan@0
|
96 quests = {},
|
jcallahan@167
|
97 spells = {},
|
MMOSimca@550
|
98 world_quests = {},
|
jcallahan@17
|
99 zones = {},
|
jcallahan@0
|
100 }
|
jcallahan@0
|
101 }
|
jcallahan@0
|
102
|
jcallahan@1
|
103 local EVENT_MAPPING = {
|
MMOSimca@436
|
104 AUCTION_HOUSE_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
105 AUCTION_HOUSE_SHOW = true, -- also triggers StopChatLootRecording
|
MMOSimca@436
|
106 BANKFRAME_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
107 BANKFRAME_OPENED = true, -- also triggers StopChatLootRecording
|
jcallahan@90
|
108 BATTLEFIELDS_SHOW = true,
|
jcallahan@56
|
109 BLACK_MARKET_ITEM_UPDATE = true,
|
MMOSimca@408
|
110 BONUS_ROLL_RESULT = true,
|
MMOSimca@388
|
111 CHAT_MSG_CURRENCY = true,
|
jcallahan@48
|
112 CHAT_MSG_LOOT = true,
|
jcallahan@95
|
113 CHAT_MSG_MONSTER_SAY = "RecordQuote",
|
jcallahan@95
|
114 CHAT_MSG_MONSTER_WHISPER = "RecordQuote",
|
jcallahan@95
|
115 CHAT_MSG_MONSTER_YELL = "RecordQuote",
|
jcallahan@40
|
116 CHAT_MSG_SYSTEM = true,
|
MMOSimca@581
|
117 WORLD_CURSOR_TOOLTIP_UPDATE = true,
|
MMOSimca@436
|
118 GARRISON_MISSION_NPC_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
119 GARRISON_MISSION_NPC_OPENED = "StopChatLootRecording",
|
MMOSimca@450
|
120 GARRISON_SHIPYARD_NPC_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@450
|
121 GARRISON_SHIPYARD_NPC_OPENED = "StopChatLootRecording",
|
MMOSimca@436
|
122 GOSSIP_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
123 GOSSIP_SHOW = true, -- also triggers StopChatLootRecording
|
jcallahan@290
|
124 GROUP_ROSTER_UPDATE = true,
|
MMOSimca@436
|
125 GUILDBANKFRAME_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
126 GUILDBANKFRAME_OPENED = true, -- also triggers StopChatLootRecording
|
atcaleb@573
|
127 ISLAND_AZERITE_GAIN = true,
|
atcaleb@573
|
128 ISLAND_COMPLETED = true,
|
jcallahan@42
|
129 ITEM_TEXT_BEGIN = true,
|
jcallahan@124
|
130 LOOT_CLOSED = true,
|
MMOSimca@343
|
131 LOOT_OPENED = true,
|
MMOSimca@412
|
132 LOOT_SLOT_CLEARED = "HandleBadChatLootData",
|
MMOSimca@436
|
133 MAIL_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@436
|
134 MAIL_SHOW = true, -- also triggers StopChatLootRecording
|
MMOSimca@436
|
135 MERCHANT_CLOSED = true, -- also triggers ResumeChatLootRecording
|
MMOSimca@436
|
136 MERCHANT_SHOW = "UpdateMerchantItems", -- also triggers StopChatLootRecording
|
jcallahan@61
|
137 MERCHANT_UPDATE = "UpdateMerchantItems",
|
jcallahan@25
|
138 PET_BAR_UPDATE = true,
|
MMOSimca@368
|
139 --PET_JOURNAL_LIST_UPDATE = true,
|
jcallahan@156
|
140 PLAYER_REGEN_DISABLED = true,
|
jcallahan@156
|
141 PLAYER_REGEN_ENABLED = true,
|
jcallahan@2
|
142 PLAYER_TARGET_CHANGED = true,
|
jcallahan@9
|
143 QUEST_COMPLETE = true,
|
jcallahan@9
|
144 QUEST_DETAIL = true,
|
jcallahan@9
|
145 QUEST_LOG_UPDATE = true,
|
jcallahan@97
|
146 QUEST_PROGRESS = true,
|
jcallahan@178
|
147 SHOW_LOOT_TOAST = true,
|
jcallahan@306
|
148 SPELL_CONFIRMATION_PROMPT = true,
|
jcallahan@88
|
149 TAXIMAP_OPENED = true,
|
MMOSimca@437
|
150 TRADE_CLOSED = "ResumeChatLootRecording",
|
MMOSimca@437
|
151 TRADE_SHOW = "StopChatLootRecording",
|
MMOSimca@581
|
152 --TRADE_SKILL_SHOW = true,
|
MMOSimca@581
|
153 --TRAINER_CLOSED = true,
|
MMOSimca@581
|
154 --TRAINER_SHOW = true,
|
jcallahan@246
|
155 UNIT_PET = true,
|
jcallahan@4
|
156 UNIT_QUEST_LOG_CHANGED = true,
|
MMOSimca@581
|
157 PLAYER_INTERACTION_MANAGER_FRAME_SHOW = true,
|
jcallahan@0
|
158 }
|
jcallahan@0
|
159
|
jcallahan@4
|
160
|
jcallahan@246
|
161 -- VARIABLES ----------------------------------------------------------
|
jcallahan@246
|
162
|
jcallahan@92
|
163 local anvil_spell_ids = {}
|
jcallahan@92
|
164 local currently_drunk
|
jcallahan@128
|
165 local char_db
|
jcallahan@128
|
166 local global_db
|
jcallahan@299
|
167 local group_member_guids = {}
|
jcallahan@246
|
168 local group_owner_guids_to_pet_guids = {}
|
jcallahan@246
|
169 local group_pet_guids = {}
|
jcallahan@299
|
170 local in_instance
|
jcallahan@187
|
171 local item_process_timer_handle
|
jcallahan@92
|
172 local faction_standings = {}
|
jcallahan@92
|
173 local forge_spell_ids = {}
|
jcallahan@95
|
174 local languages_known = {}
|
jcallahan@317
|
175 local boss_loot_toasting = {}
|
MMOSimca@387
|
176 local container_loot_toasting
|
MMOSimca@387
|
177 local loot_toast_container_id
|
MMOSimca@387
|
178 local raid_boss_id
|
jcallahan@306
|
179 local loot_toast_container_timer_handle
|
jcallahan@307
|
180 local loot_toast_data
|
jcallahan@307
|
181 local loot_toast_data_timer_handle
|
jcallahan@95
|
182 local name_to_id_map = {}
|
jcallahan@306
|
183 local killed_boss_id_timer_handle
|
jcallahan@177
|
184 local killed_npc_id
|
jcallahan@2
|
185 local target_location_timer_handle
|
MMOSimca@345
|
186 local last_timber_spell_id
|
MMOSimca@355
|
187 local last_garrison_cache_object_id
|
MMOSimca@436
|
188 local block_chat_loot_data
|
MMOSimca@435
|
189 local chat_loot_data = {}
|
MMOSimca@347
|
190 local chat_loot_timer_handle
|
mmosimca@485
|
191 local world_quest_timer_handle
|
mmosimca@485
|
192 local world_quest_event_timestamp = 0
|
atcaleb@573
|
193 local killed_npcs_in_island = {}
|
atcaleb@573
|
194 local island_difficulty_token
|
jcallahan@86
|
195 local current_target_id
|
jcallahan@131
|
196 local current_loot
|
jcallahan@1
|
197
|
jcallahan@312
|
198
|
jcallahan@121
|
199 -- Data for our current action. Including possible values as a reference.
|
jcallahan@122
|
200 local current_action = {
|
jcallahan@121
|
201 identifier = nil,
|
jcallahan@121
|
202 loot_label = nil,
|
jcallahan@121
|
203 loot_list = nil,
|
jcallahan@121
|
204 loot_sources = nil,
|
jcallahan@121
|
205 map_level = nil,
|
jcallahan@121
|
206 spell_label = nil,
|
jcallahan@123
|
207 target_type = nil,
|
jcallahan@121
|
208 x = nil,
|
jcallahan@121
|
209 y = nil,
|
jcallahan@121
|
210 zone_data = nil,
|
jcallahan@121
|
211 }
|
jcallahan@92
|
212
|
jcallahan@246
|
213
|
MMOSimca@393
|
214 -- Timer prototypes
|
MMOSimca@393
|
215 local ClearKilledNPC, ClearKilledBossID, ClearLootToastContainerID, ClearLootToastData, ClearChatLootData
|
MMOSimca@393
|
216
|
MMOSimca@393
|
217
|
jcallahan@246
|
218 -- HELPERS ------------------------------------------------------------
|
jcallahan@246
|
219
|
jcallahan@245
|
220 local function Debug(message, ...)
|
MMOSimca@350
|
221 if not DEBUGGING or not message then
|
jcallahan@151
|
222 return
|
jcallahan@151
|
223 end
|
catherton@465
|
224
|
MMOSimca@350
|
225 if ... then
|
MMOSimca@350
|
226 local args = { ... }
|
MMOSimca@350
|
227
|
MMOSimca@350
|
228 for index = 1, #args do
|
MMOSimca@377
|
229 args[index] = tostring(args[index])
|
jcallahan@306
|
230 end
|
MMOSimca@350
|
231 _G.print(message:format(unpack(args)))
|
MMOSimca@350
|
232 else
|
MMOSimca@350
|
233 _G.print(message)
|
jcallahan@306
|
234 end
|
jcallahan@151
|
235 end
|
jcallahan@151
|
236
|
jcallahan@151
|
237
|
MMOSimca@393
|
238 local function InitializeCurrentLoot()
|
MMOSimca@393
|
239 current_loot = {
|
MMOSimca@393
|
240 list = {},
|
MMOSimca@393
|
241 sources = {},
|
MMOSimca@393
|
242 identifier = current_action.identifier,
|
MMOSimca@393
|
243 label = current_action.loot_label or "drops",
|
MMOSimca@393
|
244 map_level = current_action.map_level,
|
MMOSimca@393
|
245 object_name = current_action.object_name,
|
MMOSimca@393
|
246 spell_label = current_action.spell_label,
|
MMOSimca@393
|
247 target_type = current_action.target_type,
|
MMOSimca@393
|
248 x = current_action.x,
|
MMOSimca@393
|
249 y = current_action.y,
|
MMOSimca@393
|
250 zone_data = current_action.zone_data,
|
MMOSimca@393
|
251 }
|
MMOSimca@393
|
252
|
MMOSimca@393
|
253 table.wipe(current_action)
|
MMOSimca@393
|
254 end
|
MMOSimca@393
|
255
|
MMOSimca@393
|
256
|
jcallahan@169
|
257 local TradeSkillExecutePer
|
jcallahan@169
|
258 do
|
jcallahan@169
|
259 local header_list = {}
|
jcallahan@169
|
260
|
jcallahan@169
|
261 function TradeSkillExecutePer(iter_func)
|
jcallahan@169
|
262 if not _G.TradeSkillFrame or not _G.TradeSkillFrame:IsVisible() then
|
jcallahan@169
|
263 return
|
jcallahan@169
|
264 end
|
catherton@465
|
265
|
catherton@479
|
266 local recipes = _G.C_TradeSkillUI.GetAllRecipeIDs()
|
catherton@479
|
267
|
catherton@479
|
268 if recipes and (#recipes > 0) then
|
catherton@479
|
269 for i = 1, #recipes do
|
catherton@479
|
270 if iter_func(_G.C_TradeSkillUI.GetRecipeInfo(recipes[i]).name, recipes[i]) then
|
catherton@465
|
271 break
|
catherton@465
|
272 end
|
catherton@465
|
273 end
|
catherton@465
|
274 end
|
jcallahan@167
|
275 end
|
jcallahan@169
|
276 end -- do-block
|
jcallahan@167
|
277
|
jcallahan@167
|
278
|
jcallahan@39
|
279 local ActualCopperCost
|
jcallahan@39
|
280 do
|
jcallahan@39
|
281 local BARTERING_SPELL_ID = 83964
|
jcallahan@39
|
282
|
jcallahan@39
|
283 function ActualCopperCost(copper_cost, rep_standing)
|
jcallahan@39
|
284 if not copper_cost or copper_cost == 0 then
|
jcallahan@39
|
285 return 0
|
jcallahan@39
|
286 end
|
jcallahan@39
|
287 local modifier = 1
|
jcallahan@39
|
288
|
jcallahan@39
|
289 if _G.IsSpellKnown(BARTERING_SPELL_ID) then
|
jcallahan@39
|
290 modifier = modifier - 0.1
|
jcallahan@39
|
291 end
|
jcallahan@39
|
292
|
jcallahan@39
|
293 if rep_standing then
|
jcallahan@39
|
294 if PLAYER_RACE == "Goblin" then
|
atcaleb@558
|
295 modifier = modifier - private.STANDING_DISCOUNTS["EXALTED"]
|
atcaleb@558
|
296 elseif private.STANDING_DISCOUNTS[rep_standing] then
|
atcaleb@558
|
297 modifier = modifier - private.STANDING_DISCOUNTS[rep_standing]
|
jcallahan@39
|
298 end
|
jcallahan@39
|
299 end
|
jcallahan@39
|
300 return math.floor(copper_cost / modifier)
|
jcallahan@39
|
301 end
|
jcallahan@39
|
302 end -- do-block
|
jcallahan@39
|
303
|
jcallahan@39
|
304
|
jcallahan@29
|
305 local function InstanceDifficultyToken()
|
MMOSimca@440
|
306 -- Sometimes, instance information is returned when not in an instance. This check protects against that.
|
MMOSimca@440
|
307 if _G.IsInInstance() then
|
MMOSimca@440
|
308 local _, instance_type, instance_difficulty, _, _, _, is_dynamic = _G.GetInstanceInfo()
|
MMOSimca@440
|
309
|
MMOSimca@440
|
310 if not instance_type or instance_type == "" then
|
MMOSimca@440
|
311 instance_type = "NONE"
|
MMOSimca@440
|
312 end
|
MMOSimca@440
|
313 return ("%s:%d:%s"):format(instance_type:upper(), instance_difficulty, tostring(is_dynamic))
|
jcallahan@59
|
314 end
|
MMOSimca@440
|
315 return "NONE:0:false"
|
jcallahan@29
|
316 end
|
jcallahan@29
|
317
|
jcallahan@29
|
318
|
jcallahan@1
|
319 local function CurrentLocationData()
|
mmosimca@488
|
320 local x, y, current_area_id, map_level, map_file, is_micro_dungeon = HereBeDragons:GetPlayerZonePosition(false)
|
catherton@468
|
321 local zone_name = _G.GetRealZoneText()
|
catherton@465
|
322
|
mmosimca@488
|
323 -- Remove micro-dungeon-ness by translating back to the parent world map (at floor 0) if possible
|
mmosimca@488
|
324 if (is_micro_dungeon and x and y and current_area_id and map_level and map_level > 0) then
|
mmosimca@488
|
325 x, y = HereBeDragons:TranslateZoneCoordinates(x, y, current_area_id, map_level, current_area_id, 0, false)
|
mmosimca@488
|
326 map_level = 0
|
mmosimca@488
|
327 end
|
mmosimca@488
|
328
|
catherton@465
|
329 -- Put coordinates into expected format (as integers, they don't get a billion decimals output in the SavedVariables)
|
catherton@468
|
330 local x_int = nil
|
catherton@468
|
331 if (x and type(x) == "number") then
|
catherton@468
|
332 x_int = _G.floor(x * 1000)
|
mmosimca@485
|
333
|
mmosimca@482
|
334 -- Limit precision to 0.2
|
catherton@468
|
335 if x_int % 2 ~= 0 then
|
catherton@468
|
336 x_int = x_int + 1
|
catherton@468
|
337 end
|
mmosimca@485
|
338
|
mmosimca@482
|
339 -- Prevent out of bounds coordinates
|
mmosimca@482
|
340 if (x_int < 0 or x_int > 1000) then
|
mmosimca@482
|
341 x_int = nil
|
mmosimca@482
|
342 end
|
jcallahan@145
|
343 end
|
catherton@468
|
344 local y_int = nil
|
catherton@468
|
345 if (y and type(y) == "number") then
|
catherton@468
|
346 y_int = _G.floor(y * 1000)
|
mmosimca@485
|
347
|
mmosimca@482
|
348 -- Limit precision to 0.2
|
catherton@468
|
349 if y_int % 2 ~= 0 then
|
catherton@468
|
350 y_int = y_int + 1
|
catherton@468
|
351 end
|
mmosimca@485
|
352
|
mmosimca@482
|
353 -- Prevent out of bounds coordinates
|
mmosimca@482
|
354 if (y_int < 0 or y_int > 1000) then
|
mmosimca@482
|
355 y_int = nil
|
mmosimca@482
|
356 end
|
jcallahan@1
|
357 end
|
jcallahan@1
|
358
|
catherton@468
|
359 return zone_name, current_area_id, x_int, y_int, map_level, InstanceDifficultyToken()
|
jcallahan@1
|
360 end
|
jcallahan@1
|
361
|
jcallahan@1
|
362
|
MMOSimca@441
|
363 local function DBEntry(data_type, unit_id)
|
MMOSimca@441
|
364 if not data_type or not unit_id then
|
jcallahan@312
|
365 return
|
jcallahan@312
|
366 end
|
MMOSimca@441
|
367 local category = global_db[data_type]
|
MMOSimca@441
|
368
|
MMOSimca@441
|
369 if not category then
|
MMOSimca@441
|
370 category = {}
|
MMOSimca@441
|
371 global_db[data_type] = category
|
MMOSimca@441
|
372 end
|
MMOSimca@441
|
373 local unit = category[unit_id]
|
MMOSimca@441
|
374
|
MMOSimca@441
|
375 if not unit then
|
MMOSimca@441
|
376 unit = {}
|
MMOSimca@441
|
377 category[unit_id] = unit
|
MMOSimca@441
|
378 end
|
MMOSimca@441
|
379 return unit
|
jcallahan@312
|
380 end
|
jcallahan@312
|
381
|
MMOSimca@441
|
382 private.DBEntry = DBEntry
|
MMOSimca@441
|
383
|
MMOSimca@441
|
384 local NPCEntry
|
MMOSimca@441
|
385 do
|
MMOSimca@441
|
386 local npc_prototype = {}
|
MMOSimca@441
|
387 local npc_meta = {
|
MMOSimca@441
|
388 __index = npc_prototype
|
MMOSimca@441
|
389 }
|
MMOSimca@441
|
390
|
MMOSimca@441
|
391 function NPCEntry(identifier)
|
MMOSimca@441
|
392 local npc = DBEntry("npcs", identifier)
|
MMOSimca@441
|
393 return npc and _G.setmetatable(npc, npc_meta) or nil
|
jcallahan@1
|
394 end
|
MMOSimca@441
|
395
|
MMOSimca@441
|
396 function npc_prototype:EncounterData(difficulty_token)
|
MMOSimca@441
|
397 self.encounter_data = self.encounter_data or {}
|
MMOSimca@441
|
398 self.encounter_data[difficulty_token] = self.encounter_data[difficulty_token] or {}
|
MMOSimca@441
|
399 self.encounter_data[difficulty_token].stats = self.encounter_data[difficulty_token].stats or {}
|
MMOSimca@441
|
400
|
MMOSimca@441
|
401 return self.encounter_data[difficulty_token]
|
MMOSimca@441
|
402 end
|
jcallahan@1
|
403 end
|
jcallahan@270
|
404
|
jcallahan@4
|
405
|
jcallahan@141
|
406 local UpdateDBEntryLocation
|
jcallahan@141
|
407 do
|
jcallahan@141
|
408 -- Fishing node coordinate code based on code in GatherMate2 with permission from Kagaro.
|
jcallahan@141
|
409 local function FishingCoordinates(x, y, yard_width, yard_height)
|
jcallahan@141
|
410 local facing = _G.GetPlayerFacing()
|
jcallahan@141
|
411
|
jcallahan@141
|
412 if not facing then
|
jcallahan@141
|
413 return x, y
|
jcallahan@141
|
414 end
|
jcallahan@246
|
415 local rad = facing + math.pi
|
jcallahan@141
|
416 return x + math.sin(rad) * 15 / yard_width, y + math.cos(rad) * 15 / yard_height
|
jcallahan@10
|
417 end
|
jcallahan@10
|
418
|
jcallahan@24
|
419
|
jcallahan@141
|
420 function UpdateDBEntryLocation(entry_type, identifier)
|
jcallahan@141
|
421 if not identifier then
|
jcallahan@141
|
422 return
|
jcallahan@141
|
423 end
|
jcallahan@141
|
424 local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
|
MMOSimca@328
|
425 if not (zone_name and area_id and x and y and map_level) then
|
mmosimca@508
|
426 if not (_G.IsInInstance()) then
|
mmosimca@508
|
427 Debug("UpdateDBEntryLocation: Missing current location data - %s, %s, %s, %s, %s.", tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
|
mmosimca@508
|
428 end
|
MMOSimca@328
|
429 return
|
MMOSimca@328
|
430 end
|
jcallahan@141
|
431 local entry = DBEntry(entry_type, identifier)
|
jcallahan@141
|
432 entry[difficulty_token] = entry[difficulty_token] or {}
|
jcallahan@141
|
433 entry[difficulty_token].locations = entry[difficulty_token].locations or {}
|
jcallahan@141
|
434
|
jcallahan@141
|
435 local zone_token = ("%s:%d"):format(zone_name, area_id)
|
jcallahan@141
|
436 local zone_data = entry[difficulty_token].locations[zone_token]
|
jcallahan@141
|
437
|
jcallahan@141
|
438 if not zone_data then
|
jcallahan@141
|
439 zone_data = {}
|
jcallahan@141
|
440 entry[difficulty_token].locations[zone_token] = zone_data
|
jcallahan@141
|
441 end
|
jcallahan@141
|
442
|
jcallahan@141
|
443 -- Special case for Fishing.
|
jcallahan@141
|
444 if current_action.spell_label == "FISHING" then
|
atcaleb@561
|
445 local _, q_vector = _G.C_Map.GetWorldPosFromMapPos(area_id, _G.CreateVector2D(0,0))
|
atcaleb@561
|
446 local _, w_vector = _G.C_Map.GetWorldPosFromMapPos(area_id, _G.CreateVector2D(1,1))
|
atcaleb@561
|
447 local yard_width, yard_height = q_vector.y - w_vector.y, q_vector.x - w_vector.x
|
jcallahan@141
|
448
|
jcallahan@141
|
449 if yard_width > 0 and yard_height > 0 then
|
jcallahan@141
|
450 x, y = FishingCoordinates(x, y, yard_width, yard_height)
|
jcallahan@141
|
451 current_action.x = x
|
jcallahan@141
|
452 current_action.y = y
|
jcallahan@141
|
453 end
|
jcallahan@141
|
454 end
|
jcallahan@141
|
455 local location_token = ("%d:%d:%d"):format(map_level, x, y)
|
jcallahan@141
|
456
|
jcallahan@141
|
457 zone_data[location_token] = zone_data[location_token] or true
|
jcallahan@141
|
458 return zone_data
|
jcallahan@10
|
459 end
|
jcallahan@141
|
460 end -- do-block
|
jcallahan@10
|
461
|
jcallahan@10
|
462
|
mmosimca@496
|
463 local function CurrencyLinkToID(currency_link)
|
MMOSimca@441
|
464 if not currency_link then
|
mmosimca@496
|
465 return nil
|
MMOSimca@441
|
466 end
|
MMOSimca@540
|
467 return tonumber(tostring(currency_link):match("currency:(%d+)"))
|
MMOSimca@441
|
468 end
|
MMOSimca@441
|
469
|
MMOSimca@441
|
470
|
MMOSimca@441
|
471 local function ItemLinkToID(item_link)
|
MMOSimca@441
|
472 if not item_link then
|
MMOSimca@441
|
473 return
|
MMOSimca@441
|
474 end
|
MMOSimca@441
|
475 return tonumber(tostring(item_link):match("item:(%d+)"))
|
MMOSimca@441
|
476 end
|
MMOSimca@441
|
477
|
MMOSimca@441
|
478 private.ItemLinkToID = ItemLinkToID
|
MMOSimca@441
|
479
|
MMOSimca@441
|
480 local function UnitTypeIsNPC(unit_type)
|
MMOSimca@441
|
481 return unit_type == private.UNIT_TYPES.NPC or unit_type == private.UNIT_TYPES.VEHICLE
|
MMOSimca@441
|
482 end
|
MMOSimca@441
|
483
|
MMOSimca@441
|
484
|
MMOSimca@441
|
485 local ParseGUID
|
MMOSimca@441
|
486 do
|
MMOSimca@441
|
487 local UNIT_TYPES = private.UNIT_TYPES
|
MMOSimca@441
|
488
|
MMOSimca@441
|
489 local NPC_ID_MAPPING = {
|
MMOSimca@441
|
490 [62164] = 63191, -- Garalon
|
MMOSimca@441
|
491 }
|
MMOSimca@441
|
492
|
MMOSimca@441
|
493
|
MMOSimca@441
|
494 local function MatchUnitTypes(unit_type_name)
|
MMOSimca@441
|
495 if not unit_type_name then
|
MMOSimca@441
|
496 return UNIT_TYPES.UNKNOWN
|
MMOSimca@441
|
497 end
|
MMOSimca@441
|
498
|
MMOSimca@441
|
499 for def, text in next, UNIT_TYPES do
|
MMOSimca@441
|
500 if unit_type_name == text then
|
MMOSimca@441
|
501 return UNIT_TYPES[def]
|
MMOSimca@441
|
502 end
|
MMOSimca@441
|
503 end
|
MMOSimca@441
|
504 return UNIT_TYPES.UNKNOWN
|
MMOSimca@441
|
505 end
|
MMOSimca@441
|
506
|
MMOSimca@441
|
507
|
MMOSimca@441
|
508 function ParseGUID(guid)
|
MMOSimca@441
|
509 if not guid then
|
MMOSimca@441
|
510 return
|
MMOSimca@441
|
511 end
|
MMOSimca@441
|
512
|
MMOSimca@441
|
513 -- We might want to use some of this new information later, but leaving the returns alone for now
|
mmosimca@497
|
514 local guid_pieces = { ("-"):split(guid) }
|
mmosimca@497
|
515 local unit_type_name, unk_field, server_id, instance_id, zone_uid, unit_id, spawn_uid, player_uid = guid_pieces[1]
|
MMOSimca@441
|
516
|
MMOSimca@441
|
517 local unit_type = MatchUnitTypes(unit_type_name)
|
mmosimca@518
|
518
|
mmosimca@497
|
519 -- Creatures, GameObjects, Vehicles, and Vignettes
|
MMOSimca@441
|
520 if unit_type ~= UNIT_TYPES.PLAYER and unit_type ~= UNIT_TYPES.PET and unit_type ~= UNIT_TYPES.ITEM then
|
mmosimca@497
|
521 unk_field, server_id, instance_id, zone_uid, unit_id, spawn_uid = guid_pieces[2], guid_pieces[3], guid_pieces[4], guid_pieces[5], guid_pieces[6], guid_pieces[7]
|
mmosimca@497
|
522
|
mmosimca@497
|
523 local id_mapping = NPC_ID_MAPPING[unit_id]
|
MMOSimca@441
|
524
|
MMOSimca@441
|
525 if id_mapping and UnitTypeIsNPC(unit_type) then
|
mmosimca@497
|
526 unit_id = id_mapping
|
MMOSimca@441
|
527 end
|
mmosimca@497
|
528
|
mmosimca@497
|
529 -- Players
|
mmosimca@497
|
530 elseif unit_type == UNIT_TYPES.PLAYER then
|
mmosimca@497
|
531 server_id, player_uid = guid_pieces[2], guid_pieces[3]
|
mmosimca@497
|
532
|
mmosimca@497
|
533 -- Items
|
mmosimca@497
|
534 elseif unit_type == UNIT_TYPES.ITEM then
|
mmosimca@497
|
535 server_id, unk_field, spawn_uid = guid_pieces[2], guid_pieces[3], guid_pieces[4]
|
MMOSimca@441
|
536 end
|
mmosimca@518
|
537
|
mmosimca@497
|
538 -- Pets and other (i.e. do nothing)
|
mmosimca@497
|
539 return unit_type, unit_id
|
MMOSimca@441
|
540 end
|
MMOSimca@441
|
541
|
MMOSimca@441
|
542 private.ParseGUID = ParseGUID
|
MMOSimca@441
|
543 end -- do-block
|
MMOSimca@441
|
544
|
MMOSimca@441
|
545
|
jcallahan@19
|
546 local function HandleItemUse(item_link, bag_index, slot_index)
|
jcallahan@19
|
547 if not item_link then
|
jcallahan@19
|
548 return
|
jcallahan@19
|
549 end
|
jcallahan@19
|
550 local item_id = ItemLinkToID(item_link)
|
jcallahan@19
|
551
|
jcallahan@19
|
552 if not bag_index or not slot_index then
|
jcallahan@19
|
553 for new_bag_index = 0, _G.NUM_BAG_FRAMES do
|
MMOSimca@581
|
554 for new_slot_index = 1, _G.C_Container.GetContainerNumSlots(new_bag_index) do
|
MMOSimca@581
|
555 if item_id == ItemLinkToID(_G.C_Container.GetContainerItemLink(new_bag_index, new_slot_index)) then
|
jcallahan@19
|
556 bag_index = new_bag_index
|
jcallahan@19
|
557 slot_index = new_slot_index
|
jcallahan@19
|
558 break
|
jcallahan@19
|
559 end
|
jcallahan@19
|
560 end
|
jcallahan@19
|
561 end
|
jcallahan@19
|
562 end
|
jcallahan@19
|
563
|
MMOSimca@410
|
564 local any_loot = false
|
MMOSimca@410
|
565
|
MMOSimca@411
|
566 -- Check if Blizzard has marked this item as officially having a chance of containing loot
|
MMOSimca@410
|
567 if bag_index and slot_index then
|
MMOSimca@581
|
568 local _, _, _, _, _, is_lootable = _G.C_Container.GetContainerItemInfo(bag_index, slot_index)
|
MMOSimca@410
|
569 if is_lootable then
|
MMOSimca@410
|
570 any_loot = true
|
MMOSimca@410
|
571 end
|
jcallahan@19
|
572 end
|
catherton@465
|
573
|
MMOSimca@410
|
574 -- Check if we've marked this item as one Blizzard provides bad is_lootable data for
|
MMOSimca@410
|
575 if private.CONTAINER_ITEM_ID_LIST[item_id] ~= nil then
|
MMOSimca@410
|
576 any_loot = true
|
jcallahan@19
|
577 end
|
MMOSimca@368
|
578
|
MMOSimca@436
|
579 -- Going to block 'chat-loot data' at this level for now because I don't think we actually want normal item containers being recorded in these scenarios either.
|
MMOSimca@436
|
580 if any_loot and not block_chat_loot_data then
|
MMOSimca@414
|
581 -- For item containers that open instantly with no spell cast
|
MMOSimca@410
|
582 if (private.CONTAINER_ITEM_ID_LIST[item_id] == true) and ((not _G.GetNumLootItems()) or (_G.GetNumLootItems() == 0)) then
|
MMOSimca@410
|
583 ClearChatLootData()
|
MMOSimca@410
|
584 Debug("HandleItemUse: Beginning chat-based loot timer for item with ID %d.", item_id)
|
MMOSimca@423
|
585 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
|
atcaleb@573
|
586 chat_loot_data.category = AF.ITEM
|
MMOSimca@414
|
587 chat_loot_data.identifier = item_id
|
MMOSimca@414
|
588 -- For normal item containers
|
MMOSimca@414
|
589 else
|
MMOSimca@414
|
590 table.wipe(current_action)
|
MMOSimca@414
|
591 current_loot = nil
|
MMOSimca@414
|
592 current_action.target_type = AF.ITEM
|
MMOSimca@414
|
593 current_action.identifier = item_id
|
MMOSimca@414
|
594 current_action.loot_label = "contains"
|
MMOSimca@410
|
595 end
|
MMOSimca@393
|
596 end
|
jcallahan@19
|
597 end
|
jcallahan@19
|
598
|
jcallahan@19
|
599
|
jcallahan@39
|
600 local UnitFactionStanding
|
jcallahan@32
|
601 local UpdateFactionData
|
jcallahan@32
|
602 do
|
jcallahan@32
|
603 local MAX_FACTION_INDEX = 1000
|
jcallahan@20
|
604
|
jcallahan@32
|
605 local STANDING_NAMES = {
|
jcallahan@32
|
606 "HATED",
|
jcallahan@32
|
607 "HOSTILE",
|
jcallahan@32
|
608 "UNFRIENDLY",
|
jcallahan@32
|
609 "NEUTRAL",
|
jcallahan@32
|
610 "FRIENDLY",
|
jcallahan@32
|
611 "HONORED",
|
jcallahan@32
|
612 "REVERED",
|
jcallahan@32
|
613 "EXALTED",
|
jcallahan@32
|
614 }
|
jcallahan@32
|
615
|
jcallahan@39
|
616
|
jcallahan@39
|
617 function UnitFactionStanding(unit)
|
jcallahan@135
|
618 local unit_name = _G.UnitName(unit)
|
jcallahan@39
|
619 UpdateFactionData()
|
jcallahan@39
|
620 DatamineTT:ClearLines()
|
jcallahan@39
|
621 DatamineTT:SetUnit(unit)
|
jcallahan@39
|
622
|
jcallahan@39
|
623 for line_index = 1, DatamineTT:NumLines() do
|
jcallahan@64
|
624 local faction_name = _G["WDPDatamineTTTextLeft" .. line_index]:GetText():trim()
|
jcallahan@39
|
625
|
jcallahan@135
|
626 if faction_name and faction_name ~= unit_name and faction_standings[faction_name] then
|
jcallahan@39
|
627 return faction_name, faction_standings[faction_name]
|
jcallahan@39
|
628 end
|
jcallahan@39
|
629 end
|
jcallahan@39
|
630 end
|
jcallahan@39
|
631
|
jcallahan@39
|
632
|
jcallahan@32
|
633 function UpdateFactionData()
|
jcallahan@32
|
634 for faction_index = 1, MAX_FACTION_INDEX do
|
MMOSimca@581
|
635 local faction_table = _G.C_Reputation.GetFactionDataByIndex(faction_index)
|
MMOSimca@581
|
636
|
MMOSimca@581
|
637 if faction_table then
|
MMOSimca@581
|
638 if faction_table.name then
|
MMOSimca@581
|
639 faction_standings[faction_table.name] = STANDING_NAMES[faction_table.currentStanding]
|
MMOSimca@581
|
640 elseif not faction_table.name then
|
MMOSimca@581
|
641 break
|
MMOSimca@581
|
642 end
|
MMOSimca@581
|
643 end
|
jcallahan@20
|
644 end
|
jcallahan@20
|
645 end
|
jcallahan@32
|
646 end -- do-block
|
jcallahan@20
|
647
|
jcallahan@48
|
648
|
MMOSimca@429
|
649 local GenericLootUpdate, LootTable
|
jcallahan@75
|
650 do
|
MMOSimca@429
|
651 function LootTable(entry, loot_type, top_field)
|
jcallahan@75
|
652 if top_field then
|
jcallahan@75
|
653 entry[top_field] = entry[top_field] or {}
|
jcallahan@75
|
654 entry[top_field][loot_type] = entry[top_field][loot_type] or {}
|
jcallahan@75
|
655 return entry[top_field][loot_type]
|
jcallahan@75
|
656 end
|
jcallahan@48
|
657 entry[loot_type] = entry[loot_type] or {}
|
jcallahan@75
|
658 return entry[loot_type]
|
jcallahan@48
|
659 end
|
jcallahan@48
|
660
|
jcallahan@75
|
661 function GenericLootUpdate(data_type, top_field)
|
jcallahan@132
|
662 local loot_type = current_loot.label
|
jcallahan@75
|
663 local loot_count = ("%s_count"):format(loot_type)
|
jcallahan@77
|
664 local source_list = {}
|
jcallahan@75
|
665
|
jcallahan@131
|
666 if current_loot.sources then
|
jcallahan@131
|
667 for source_guid, loot_data in pairs(current_loot.sources) do
|
jcallahan@304
|
668 local source_id
|
jcallahan@78
|
669
|
jcallahan@131
|
670 if current_loot.target_type == AF.ITEM then
|
jcallahan@119
|
671 -- Items return the player as the source, so we need to use the item's ID (disenchant, milling, etc)
|
jcallahan@131
|
672 source_id = current_loot.identifier
|
jcallahan@119
|
673 else
|
jcallahan@331
|
674 local _, unit_ID = ParseGUID(source_guid)
|
MMOSimca@328
|
675 if unit_ID then
|
MMOSimca@328
|
676 if current_loot.target_type == AF.OBJECT then
|
MMOSimca@328
|
677 source_id = ("%s:%s"):format(current_loot.spell_label, unit_ID)
|
MMOSimca@328
|
678 else
|
MMOSimca@328
|
679 source_id = unit_ID
|
MMOSimca@328
|
680 end
|
MMOSimca@328
|
681 end
|
jcallahan@119
|
682 end
|
jcallahan@304
|
683 local entry = DBEntry(data_type, source_id)
|
jcallahan@75
|
684
|
jcallahan@119
|
685 if entry then
|
jcallahan@119
|
686 local loot_table = LootTable(entry, loot_type, top_field)
|
jcallahan@77
|
687
|
jcallahan@304
|
688 if not source_list[source_id] then
|
jcallahan@119
|
689 if top_field then
|
jcallahan@119
|
690 entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1
|
MMOSimca@387
|
691 elseif not container_loot_toasting then
|
jcallahan@119
|
692 entry[loot_count] = (entry[loot_count] or 0) + 1
|
jcallahan@119
|
693 end
|
jcallahan@304
|
694 source_list[source_id] = true
|
jcallahan@77
|
695 end
|
jcallahan@119
|
696 UpdateDBEntryLocation(data_type, source_id)
|
jcallahan@75
|
697
|
jcallahan@309
|
698 if current_loot.target_type == AF.ZONE then
|
jcallahan@309
|
699 for item_id, quantity in pairs(loot_data) do
|
jcallahan@309
|
700 table.insert(loot_table, ("%d:%d"):format(item_id, quantity))
|
jcallahan@309
|
701 end
|
jcallahan@309
|
702 else
|
jcallahan@308
|
703 for loot_token, quantity in pairs(loot_data) do
|
mmosimca@496
|
704 local label, currency_id = (":"):split(loot_token)
|
mmosimca@496
|
705
|
mmosimca@496
|
706 if label == "currency" and currency_id then
|
mmosimca@496
|
707 -- Convert currency_id back into number from string
|
mmosimca@496
|
708 currency_id = tonumber(currency_id) or 0
|
mmosimca@496
|
709 if currency_id ~= 0 then
|
mmosimca@496
|
710 table.insert(loot_table, ("currency:%d:%d"):format(quantity, currency_id))
|
mmosimca@496
|
711 end
|
jcallahan@308
|
712 elseif loot_token == "money" then
|
jcallahan@308
|
713 table.insert(loot_table, ("money:%d"):format(quantity))
|
jcallahan@308
|
714 else
|
jcallahan@308
|
715 table.insert(loot_table, ("%d:%d"):format(loot_token, quantity))
|
jcallahan@308
|
716 end
|
jcallahan@308
|
717 end
|
jcallahan@119
|
718 end
|
jcallahan@75
|
719 end
|
jcallahan@75
|
720 end
|
jcallahan@75
|
721 end
|
jcallahan@121
|
722
|
jcallahan@121
|
723 -- This is used for Gas Extractions.
|
jcallahan@131
|
724 if #current_loot.list <= 0 then
|
jcallahan@78
|
725 return
|
jcallahan@78
|
726 end
|
jcallahan@82
|
727 local entry
|
jcallahan@82
|
728
|
jcallahan@82
|
729 -- At this point we only have a name if it's an object.
|
MMOSimca@388
|
730 -- (As of 5.x, the above statement is almost never true, but there are a few cases, like gas extractions.)
|
jcallahan@131
|
731 if current_loot.target_type == AF.OBJECT then
|
jcallahan@131
|
732 entry = DBEntry(data_type, ("%s:%s"):format(current_loot.spell_label, current_loot.object_name))
|
jcallahan@82
|
733 else
|
jcallahan@131
|
734 entry = DBEntry(data_type, current_loot.identifier)
|
jcallahan@82
|
735 end
|
jcallahan@75
|
736
|
jcallahan@75
|
737 if not entry then
|
jcallahan@75
|
738 return
|
jcallahan@75
|
739 end
|
jcallahan@77
|
740 local loot_table = LootTable(entry, loot_type, top_field)
|
jcallahan@77
|
741
|
jcallahan@307
|
742 if current_loot.identifier then
|
jcallahan@307
|
743 if not source_list[current_loot.identifier] then
|
jcallahan@307
|
744 if top_field then
|
jcallahan@307
|
745 entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1
|
jcallahan@307
|
746 else
|
jcallahan@307
|
747 entry[loot_count] = (entry[loot_count] or 0) + 1
|
jcallahan@307
|
748 end
|
jcallahan@307
|
749 source_list[current_loot.identifier] = true
|
jcallahan@77
|
750 end
|
jcallahan@77
|
751 end
|
jcallahan@75
|
752
|
jcallahan@131
|
753 for index = 1, #current_loot.list do
|
jcallahan@131
|
754 table.insert(loot_table, current_loot.list[index])
|
jcallahan@75
|
755 end
|
jcallahan@48
|
756 end
|
jcallahan@75
|
757 end -- do-block
|
jcallahan@48
|
758
|
jcallahan@97
|
759
|
jcallahan@97
|
760 local ReplaceKeywords
|
jcallahan@97
|
761 do
|
jcallahan@97
|
762 local KEYWORD_SUBSTITUTIONS = {
|
jcallahan@97
|
763 class = PLAYER_CLASS,
|
jcallahan@97
|
764 name = PLAYER_NAME,
|
jcallahan@97
|
765 race = PLAYER_RACE,
|
jcallahan@97
|
766 }
|
jcallahan@97
|
767
|
jcallahan@97
|
768
|
jcallahan@97
|
769 function ReplaceKeywords(text)
|
jcallahan@97
|
770 if not text or text == "" then
|
jcallahan@97
|
771 return ""
|
jcallahan@97
|
772 end
|
jcallahan@97
|
773
|
jcallahan@97
|
774 for category, lookup in pairs(KEYWORD_SUBSTITUTIONS) do
|
jcallahan@97
|
775 local category_format = ("<%s>"):format(category)
|
jcallahan@97
|
776 text = text:gsub(lookup, category_format):gsub(lookup:lower(), category_format)
|
jcallahan@97
|
777 end
|
jcallahan@97
|
778 return text
|
jcallahan@97
|
779 end
|
jcallahan@97
|
780 end -- do-block
|
jcallahan@97
|
781
|
jcallahan@97
|
782
|
MMOSimca@347
|
783 -- TIMERS -------------------------------------------------------------
|
MMOSimca@347
|
784
|
MMOSimca@393
|
785 function ClearKilledNPC()
|
MMOSimca@347
|
786 killed_npc_id = nil
|
MMOSimca@347
|
787 end
|
MMOSimca@347
|
788
|
MMOSimca@347
|
789
|
MMOSimca@393
|
790 function ClearKilledBossID()
|
MMOSimca@347
|
791 if killed_boss_id_timer_handle then
|
MMOSimca@383
|
792 killed_boss_id_timer_handle:Cancel()
|
MMOSimca@347
|
793 killed_boss_id_timer_handle = nil
|
MMOSimca@347
|
794 end
|
MMOSimca@347
|
795
|
MMOSimca@347
|
796 table.wipe(boss_loot_toasting)
|
MMOSimca@387
|
797 raid_boss_id = nil
|
MMOSimca@347
|
798 end
|
MMOSimca@347
|
799
|
MMOSimca@347
|
800
|
MMOSimca@393
|
801 function ClearLootToastContainerID()
|
MMOSimca@347
|
802 if loot_toast_container_timer_handle then
|
MMOSimca@383
|
803 loot_toast_container_timer_handle:Cancel()
|
MMOSimca@347
|
804 loot_toast_container_timer_handle = nil
|
MMOSimca@347
|
805 end
|
MMOSimca@347
|
806
|
MMOSimca@387
|
807 container_loot_toasting = false
|
MMOSimca@387
|
808 loot_toast_container_id = nil
|
MMOSimca@347
|
809 end
|
MMOSimca@347
|
810
|
MMOSimca@347
|
811
|
MMOSimca@393
|
812 function ClearLootToastData()
|
MMOSimca@347
|
813 if loot_toast_data_timer_handle then
|
MMOSimca@383
|
814 loot_toast_data_timer_handle:Cancel()
|
MMOSimca@347
|
815 loot_toast_data_timer_handle = nil
|
MMOSimca@347
|
816 end
|
MMOSimca@347
|
817
|
MMOSimca@347
|
818 if loot_toast_data then
|
MMOSimca@347
|
819 table.wipe(loot_toast_data)
|
MMOSimca@347
|
820 end
|
MMOSimca@347
|
821 end
|
MMOSimca@347
|
822
|
MMOSimca@347
|
823
|
MMOSimca@393
|
824 function ClearChatLootData()
|
MMOSimca@398
|
825 if not chat_loot_timer_handle then
|
MMOSimca@435
|
826 table.wipe(chat_loot_data)
|
MMOSimca@398
|
827 return
|
MMOSimca@398
|
828 end
|
MMOSimca@398
|
829 Debug("ClearChatLootData: Ending chat-based loot timer.")
|
MMOSimca@398
|
830 chat_loot_timer_handle:Cancel()
|
MMOSimca@398
|
831 chat_loot_timer_handle = nil
|
atcaleb@573
|
832
|
atcaleb@573
|
833 -- Slimmed down (and more importantly, separate) versions of GenericLootUpdate, specifically for chat_loot_data
|
atcaleb@573
|
834 -- First version is for special item containers that 'push' loot without using a loot window
|
atcaleb@573
|
835 if chat_loot_data.identifier and chat_loot_data.loot and chat_loot_data.category == AF.ITEM and private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil then
|
MMOSimca@414
|
836 local entry = DBEntry("items", chat_loot_data.identifier)
|
MMOSimca@414
|
837
|
MMOSimca@414
|
838 if entry then
|
MMOSimca@414
|
839 local loot_table = LootTable(entry, "contains")
|
MMOSimca@414
|
840 entry["contains_count"] = (entry["contains_count"] or 0) + 1
|
MMOSimca@414
|
841
|
MMOSimca@435
|
842 for loot_token, quantity in pairs(chat_loot_data.loot) do
|
mmosimca@496
|
843 local label, currency_id = (":"):split(loot_token)
|
mmosimca@496
|
844
|
mmosimca@496
|
845 if label == "currency" and currency_id then
|
mmosimca@496
|
846 -- Convert currency_id back into number from string
|
mmosimca@496
|
847 currency_id = tonumber(currency_id) or 0
|
mmosimca@496
|
848 if currency_id ~= 0 then
|
mmosimca@496
|
849 table.insert(loot_table, ("currency:%d:%d"):format(quantity, currency_id))
|
mmosimca@496
|
850 end
|
MMOSimca@414
|
851 elseif loot_token == "money" then
|
MMOSimca@414
|
852 table.insert(loot_table, ("money:%d"):format(quantity))
|
MMOSimca@414
|
853 else
|
MMOSimca@414
|
854 table.insert(loot_table, ("%d:%d"):format(loot_token, quantity))
|
MMOSimca@414
|
855 end
|
MMOSimca@414
|
856 end
|
MMOSimca@414
|
857 end
|
atcaleb@573
|
858 -- Second version is for Island Expeditions. This code is flawed (by design).
|
atcaleb@573
|
859 elseif chat_loot_data.loot and chat_loot_data.category == AF.NPC then
|
atcaleb@573
|
860 -- Iterate over all NPCs killed in an island expedition (at least by your team)
|
atcaleb@573
|
861 for island_npc_id, kill_count in pairs(killed_npcs_in_island) do
|
atcaleb@573
|
862 local npc = NPCEntry(island_npc_id)
|
atcaleb@573
|
863 if npc then
|
atcaleb@573
|
864 -- Create needed npc fields if required
|
atcaleb@573
|
865 local loot_label = "drops"
|
atcaleb@573
|
866 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
|
atcaleb@573
|
867 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
atcaleb@573
|
868 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
atcaleb@573
|
869 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + kill_count
|
atcaleb@573
|
870
|
atcaleb@573
|
871 for loot_token, quantity in pairs(chat_loot_data.loot) do
|
atcaleb@573
|
872 local label, currency_id = (":"):split(loot_token)
|
atcaleb@573
|
873
|
atcaleb@573
|
874 -- Only support items
|
atcaleb@573
|
875 if (label ~= "currency" or not currency_id) and (loot_token ~= "money") then
|
atcaleb@573
|
876 -- Ignore certain items (dubloon bags)
|
atcaleb@573
|
877 if not private.IGNORED_ISLAND_REWARDS[tonumber(loot_token)] then
|
atcaleb@573
|
878 table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
|
atcaleb@573
|
879 end
|
atcaleb@573
|
880 end
|
atcaleb@573
|
881 end
|
atcaleb@573
|
882 end
|
atcaleb@573
|
883 end
|
MMOSimca@347
|
884 end
|
atcaleb@573
|
885 table.wipe(killed_npcs_in_island)
|
MMOSimca@435
|
886 table.wipe(chat_loot_data)
|
MMOSimca@347
|
887 end
|
MMOSimca@347
|
888
|
MMOSimca@347
|
889
|
jcallahan@246
|
890 -- METHODS ------------------------------------------------------------
|
jcallahan@246
|
891
|
jcallahan@0
|
892 function WDP:OnInitialize()
|
jcallahan@128
|
893 local db = LibStub("AceDB-3.0"):New("WoWDBProfilerData", DATABASE_DEFAULTS, "Default")
|
jcallahan@270
|
894 private.db = db
|
jcallahan@128
|
895 global_db = db.global
|
jcallahan@128
|
896 char_db = db.char
|
jcallahan@14
|
897
|
jcallahan@270
|
898 local raw_db = _G.WoWDBProfilerData
|
jcallahan@18
|
899 local build_num = tonumber(private.build_num)
|
mmosimca@485
|
900
|
MMOSimca@533
|
901 -- Get current region from API (flawed)
|
MMOSimca@533
|
902 local current_region = _G.GetCurrentRegionName() or "XX"
|
mmosimca@484
|
903
|
mmosimca@484
|
904 -- Wipe all data if DB version or build number changed
|
jcallahan@136
|
905 if (raw_db.version and raw_db.version < DB_VERSION) or (raw_db.build_num and raw_db.build_num < build_num) then
|
jcallahan@74
|
906 for entry in pairs(DATABASE_DEFAULTS.global) do
|
jcallahan@128
|
907 global_db[entry] = {}
|
jcallahan@74
|
908 end
|
jcallahan@74
|
909 end
|
mmosimca@485
|
910 -- Wipe World Quest data if region changed
|
mmosimca@485
|
911 if raw_db.region and raw_db.region ~= current_region and global_db["world_quests"] then
|
mmosimca@485
|
912 global_db["world_quests"] = {}
|
mmosimca@485
|
913 end
|
mmosimca@485
|
914
|
jcallahan@35
|
915 raw_db.build_num = build_num
|
mmosimca@484
|
916 raw_db.region = current_region
|
jcallahan@63
|
917 raw_db.version = DB_VERSION
|
jcallahan@249
|
918
|
jcallahan@312
|
919 private.InitializeCommentSystem()
|
jcallahan@312
|
920 self:RegisterChatCommand("comment", private.ProcessCommentCommand)
|
jcallahan@0
|
921 end
|
jcallahan@0
|
922
|
jcallahan@0
|
923
|
jcallahan@153
|
924 function WDP:EventDispatcher(...)
|
jcallahan@153
|
925 local event_name = ...
|
jcallahan@153
|
926
|
MMOSimca@346
|
927 if DEBUGGING then
|
jcallahan@154
|
928 if event_name == "COMBAT_LOG_EVENT_UNFILTERED" then
|
jcallahan@154
|
929 Debug(event_name)
|
jcallahan@154
|
930 else
|
jcallahan@154
|
931 Debug(...)
|
jcallahan@153
|
932 end
|
jcallahan@153
|
933 end
|
jcallahan@153
|
934 local func = EVENT_MAPPING[event_name]
|
jcallahan@153
|
935
|
mmosimca@522
|
936 if type(func) == "boolean" then
|
jcallahan@153
|
937 self[event_name](self, ...)
|
mmosimca@522
|
938 elseif type(func) == "function" then
|
jcallahan@159
|
939 self[func](self, ...)
|
jcallahan@153
|
940 end
|
jcallahan@153
|
941 end
|
jcallahan@153
|
942
|
jcallahan@153
|
943
|
jcallahan@0
|
944 function WDP:OnEnable()
|
jcallahan@300
|
945 PLAYER_GUID = _G.UnitGUID("player")
|
jcallahan@300
|
946
|
jcallahan@0
|
947 for event_name, mapping in pairs(EVENT_MAPPING) do
|
jcallahan@156
|
948 if EVENT_DEBUG then
|
jcallahan@153
|
949 self:RegisterEvent(event_name, "EventDispatcher")
|
jcallahan@153
|
950 else
|
mmosimca@522
|
951 self:RegisterEvent(event_name, (type(mapping) ~= "boolean") and mapping or nil)
|
jcallahan@153
|
952 end
|
jcallahan@0
|
953 end
|
jcallahan@95
|
954
|
mmosimca@496
|
955 -- Gather known languages
|
jcallahan@95
|
956 for index = 1, _G.GetNumLanguages() do
|
jcallahan@95
|
957 languages_known[_G.GetLanguageByIndex(index)] = true
|
jcallahan@95
|
958 end
|
mmosimca@518
|
959
|
mmosimca@485
|
960 -- These timers loop indefinitely using Lua's infinity constant
|
atcaleb@562
|
961 item_process_timer_handle = C_Timer.NewTicker(DELAY_PROCESS_ITEMS, WDP.ProcessItems, nil)
|
atcaleb@562
|
962 target_location_timer_handle = C_Timer.NewTicker(DELAY_UPDATE_TARGET_LOCATION, WDP.UpdateTargetLocation, nil)
|
atcaleb@562
|
963 world_quest_timer_handle = C_Timer.NewTicker(DELAY_PROCESS_WORLD_QUESTS, WDP.ProcessWorldQuests, nil)
|
jcallahan@19
|
964
|
MMOSimca@581
|
965 _G.hooksecurefunc(C_Container, "UseContainerItem", function(bag_index, slot_index, target_unit)
|
jcallahan@19
|
966 if target_unit then
|
jcallahan@19
|
967 return
|
jcallahan@19
|
968 end
|
MMOSimca@581
|
969 HandleItemUse(_G.C_Container.GetContainerItemLink(bag_index, slot_index), bag_index, slot_index)
|
jcallahan@19
|
970 end)
|
jcallahan@19
|
971
|
MMOSimca@584
|
972 _G.hooksecurefunc(C_Item, "UseItemByName", function(identifier, target_unit)
|
jcallahan@19
|
973 if target_unit then
|
jcallahan@19
|
974 return
|
jcallahan@19
|
975 end
|
jcallahan@19
|
976 local _, item_link = _G.GetItemInfo(identifier)
|
jcallahan@19
|
977 HandleItemUse(item_link)
|
jcallahan@19
|
978 end)
|
jcallahan@263
|
979
|
jcallahan@290
|
980 self:GROUP_ROSTER_UPDATE()
|
jcallahan@0
|
981 end
|
jcallahan@0
|
982
|
jcallahan@0
|
983
|
mmosimca@485
|
984 -- Record data for a specific quest ID; reward data must be available or nothing will be recorded
|
mmosimca@485
|
985 -- When we reach this point, we've already checked for a valid mapID, questID, quest data, and worldQuestType
|
atcaleb@562
|
986 local function RecordWorldQuestData(quest_id, api_data_table)
|
atcaleb@575
|
987 local xp, _ = _G.GetQuestLogRewardXP(quest_id)
|
atcaleb@575
|
988
|
mmosimca@485
|
989 -- Ensure we have location data and rewards (barely readable so putting it on multiple lines)
|
mmosimca@487
|
990 -- (Honor is built in to the quest; it is not a sign rewards have been loaded)
|
atcaleb@562
|
991 if not api_data_table or not api_data_table.x or not api_data_table.y or not api_data_table.mapID or not
|
atcaleb@575
|
992 (xp > 0 or _G.GetNumQuestLogRewardCurrencies(quest_id) > 0
|
atcaleb@562
|
993 or _G.GetNumQuestLogRewards(quest_id) > 0 or _G.GetQuestLogRewardMoney(quest_id) > 0) then
|
atcaleb@562
|
994 --or _G.GetQuestLogRewardArtifactXP(quest_id) > 0)
|
mmosimca@485
|
995 return
|
mmosimca@485
|
996 end
|
mmosimca@485
|
997
|
mmosimca@485
|
998 local entry = DBEntry("world_quests", quest_id)
|
mmosimca@485
|
999 if entry then
|
mmosimca@485
|
1000
|
mmosimca@485
|
1001 -- Record location
|
mmosimca@485
|
1002 entry["location"] = {}
|
atcaleb@562
|
1003 entry["location"]["world_map_id"] = api_data_table.mapID
|
atcaleb@562
|
1004 entry["location"]["x"] = api_data_table.x * 100
|
atcaleb@562
|
1005 entry["location"]["y"] = api_data_table.y * 100
|
mmosimca@485
|
1006
|
mmosimca@485
|
1007 -- Record simple rewards (XP, money, artifact XP, honor)
|
mmosimca@485
|
1008 entry["rewards"] = {}
|
atcaleb@575
|
1009 entry["rewards"]["xp"] = tonumber(xp) or 0
|
mmosimca@485
|
1010 entry["rewards"]["money"] = tonumber(_G.GetQuestLogRewardMoney(quest_id)) or 0
|
atcaleb@562
|
1011 --local actualXP, scaling = _G.GetQuestLogRewardArtifactXP(quest_id)
|
atcaleb@562
|
1012 --entry["rewards"]["artifact_xp"] = ("%d:%d"):format(tonumber(actualXP) or 0, tonumber(scaling) or 0)
|
mmosimca@485
|
1013 entry["rewards"]["honor"] = tonumber(_G.GetQuestLogRewardHonor(quest_id)) or 0
|
mmosimca@485
|
1014
|
mmosimca@485
|
1015 -- Record currencies
|
mmosimca@485
|
1016 entry["rewards"]["currency_count"] = tonumber(_G.GetNumQuestLogRewardCurrencies(quest_id)) or 0
|
mmosimca@485
|
1017
|
mmosimca@496
|
1018 -- Create currency rewards sub-table and fill
|
mmosimca@485
|
1019 if entry["rewards"]["currency_count"] > 0 then
|
mmosimca@485
|
1020 entry["rewards"]["currencies"] = {}
|
mmosimca@485
|
1021 for i = 1, entry["rewards"]["currency_count"] do
|
mmosimca@503
|
1022 local name, texture_path, quantity, currency_id = _G.GetQuestLogRewardCurrencyInfo(i, quest_id)
|
mmosimca@503
|
1023 table.insert(entry["rewards"]["currencies"], ("%d:%d"):format(quantity, currency_id))
|
mmosimca@485
|
1024 end
|
mmosimca@485
|
1025 end
|
mmosimca@485
|
1026
|
mmosimca@485
|
1027 -- Record items
|
mmosimca@485
|
1028 entry["rewards"]["item_count"] = tonumber(_G.GetNumQuestLogRewards(quest_id)) or 0
|
mmosimca@485
|
1029
|
mmosimca@496
|
1030 -- Create item rewards sub-table and fill
|
mmosimca@485
|
1031 if entry["rewards"]["item_count"] > 0 then
|
mmosimca@485
|
1032 entry["rewards"]["items"] = {}
|
mmosimca@485
|
1033 for i = 1, entry["rewards"]["item_count"] do
|
mmosimca@485
|
1034 local item_name, item_texture, quantity, quality, is_usable, item_id = _G.GetQuestLogRewardInfo(i, quest_id)
|
mmosimca@485
|
1035 table.insert(entry["rewards"]["items"], ("%d:%d"):format(item_id, quantity))
|
mmosimca@485
|
1036 end
|
mmosimca@485
|
1037 end
|
mmosimca@485
|
1038
|
mmosimca@485
|
1039 -- Record time remaining
|
mmosimca@485
|
1040 entry["estimated_end_time"] = _G.GetServerTime() + ((_G.C_TaskQuest.GetQuestTimeLeftMinutes(quest_id) or 0) * 60)
|
mmosimca@485
|
1041 end
|
mmosimca@485
|
1042 end
|
mmosimca@485
|
1043
|
mmosimca@485
|
1044
|
mmosimca@485
|
1045 function WDP:ProcessWorldQuests()
|
MMOSimca@532
|
1046 -- Ignore if player is low level (there are some world quests before max level now, but we can collect enough data from 110s alone still)
|
atcaleb@562
|
1047 if _G.UnitLevel("player") < 110 then return end
|
atcaleb@559
|
1048
|
atcaleb@566
|
1049 -- Check all first-order continents
|
atcaleb@566
|
1050 local continents = C_Map.GetMapChildrenInfo(UI_MAP_COSMIC, Enum.UIMapType.Continent, true);
|
atcaleb@566
|
1051 for i, continentInfo in ipairs(continents) do
|
atcaleb@566
|
1052
|
atcaleb@566
|
1053 -- Get continent data for World Quests
|
atcaleb@566
|
1054 local continent_api_data = C_TaskQuest.GetQuestsForPlayerByMapID(continentInfo.mapID)
|
atcaleb@566
|
1055
|
atcaleb@566
|
1056 -- If the continent has WQ data, continue
|
atcaleb@566
|
1057 if continent_api_data and type(continent_api_data) == "table" and #continent_api_data > 0 then
|
atcaleb@566
|
1058 -- Iterate over zones on continents
|
atcaleb@566
|
1059 local zones = C_Map.GetMapChildrenInfo(continentInfo.mapID, Enum.UIMapType.Zone)
|
atcaleb@566
|
1060 for j, zoneInfo in ipairs(zones) do
|
atcaleb@566
|
1061
|
atcaleb@566
|
1062 -- Get zone data for World Quests
|
atcaleb@566
|
1063 local zone_api_data = C_TaskQuest.GetQuestsForPlayerByMapID(zoneInfo.mapID);
|
atcaleb@566
|
1064
|
atcaleb@566
|
1065 -- Iterate over the questIDs for each zone, doing preload reward requests and creating SavedVariables entries
|
atcaleb@566
|
1066 if zone_api_data and type(zone_api_data) == "table" and #zone_api_data > 0 then
|
atcaleb@566
|
1067 for k = 1, #zone_api_data do
|
atcaleb@566
|
1068
|
atcaleb@566
|
1069 -- Check if we had a valid API table returned to us
|
atcaleb@566
|
1070 if zone_api_data[k] and type(zone_api_data[k]) == "table" and zone_api_data[k].questId then
|
atcaleb@566
|
1071 local quest_id = tonumber(zone_api_data[k].questId) or 0
|
atcaleb@566
|
1072
|
atcaleb@566
|
1073 -- Check if we have quest data and the quest is within this zone directly
|
atcaleb@566
|
1074 if quest_id > 0 and _G.HaveQuestData(quest_id) and QuestUtils_IsQuestWorldQuest(quest_id) and zone_api_data[k].mapID == zoneInfo.mapID then
|
atcaleb@566
|
1075 _G.C_TaskQuest.RequestPreloadRewardData(quest_id)
|
atcaleb@566
|
1076 RecordWorldQuestData(quest_id, zone_api_data[k])
|
atcaleb@566
|
1077 end
|
atcaleb@566
|
1078 end
|
mmosimca@485
|
1079 end
|
mmosimca@485
|
1080 end
|
mmosimca@485
|
1081 end
|
mmosimca@485
|
1082 end
|
mmosimca@485
|
1083 end
|
mmosimca@485
|
1084 end
|
mmosimca@485
|
1085
|
mmosimca@485
|
1086
|
MMOSimca@340
|
1087 local function RecordItemData(item_id, item_link, process_bonus_ids, durability)
|
jcallahan@331
|
1088 local _, _, item_string = item_link:find("^|%x+|H(.+)|h%[.+%]")
|
jcallahan@219
|
1089 local item
|
jcallahan@0
|
1090
|
jcallahan@191
|
1091 if item_string then
|
MMOSimca@338
|
1092 local item_results = { (":"):split(item_string) }
|
MMOSimca@338
|
1093
|
MMOSimca@460
|
1094 local suffix_id = tonumber(item_results[8]) or 0
|
MMOSimca@462
|
1095 local unique_id = tonumber(item_results[9]) or 0
|
MMOSimca@447
|
1096 --local level = tonumber(item_results[10])
|
MMOSimca@460
|
1097 --local specialization_id = tonumber(item_results[11])
|
catherton@469
|
1098 --local upgrade_type_id = tonumber(item_results[12])
|
MMOSimca@460
|
1099 local instance_difficulty_id = tonumber(item_results[13]) or 0
|
MMOSimca@460
|
1100 local num_bonus_ids = tonumber(item_results[14]) or 0
|
catherton@471
|
1101 -- upgrade_value is optional in 6.2! can be detected using upgrade_type_id, but it's just as easy to check like this
|
catherton@469
|
1102 local upgrade_value = tonumber(item_results[15 + num_bonus_ids]) or 0
|
catherton@465
|
1103
|
mmosimca@484
|
1104 local unk_item_field_1 = tonumber(item_results[16 + num_bonus_ids]) or 0
|
mmosimca@484
|
1105 local unk_item_field_2 = tonumber(item_results[17 + num_bonus_ids]) or 0
|
mmosimca@484
|
1106 --if unk_item_field_1 > 0 then Debug("unk_item_field_1 for %s is non-zero, specifically %d.", item_link, unk_item_field_1) end
|
mmosimca@484
|
1107 --if unk_item_field_2 > 0 then Debug("unk_item_field_2 for %s is non-zero, specifically %d.", item_link, unk_item_field_2) end
|
MMOSimca@460
|
1108
|
MMOSimca@460
|
1109 -- If there is anything special (non-zero) for this item then we need to make note of everything
|
catherton@471
|
1110 if math.max(suffix_id, instance_difficulty_id, num_bonus_ids, upgrade_value) ~= 0 then
|
MMOSimca@460
|
1111 item = DBEntry("items", item_id)
|
MMOSimca@460
|
1112 item.suffix_id = suffix_id
|
MMOSimca@460
|
1113 item.unique_id = bit.band(unique_id, 0xFFFF)
|
MMOSimca@460
|
1114 item.instance_difficulty_id = instance_difficulty_id
|
catherton@471
|
1115 item.upgrade_value = upgrade_value
|
MMOSimca@460
|
1116
|
MMOSimca@460
|
1117 if process_bonus_ids then
|
MMOSimca@460
|
1118
|
MMOSimca@460
|
1119 -- Get ready for bonus IDs
|
MMOSimca@384
|
1120 if not item.seen_bonuses then
|
MMOSimca@384
|
1121 item.seen_bonuses = {}
|
MMOSimca@372
|
1122 end
|
catherton@465
|
1123
|
MMOSimca@460
|
1124 if num_bonus_ids > 0 then
|
MMOSimca@460
|
1125 -- We want the bonus ID combo output to be in the form ["bonusID1:bonusID2:bonusID3"] = true
|
MMOSimca@460
|
1126 -- And sorted numerically with the smallest bonusID first
|
MMOSimca@460
|
1127 local sorted_bonus_string = ""
|
MMOSimca@460
|
1128 local min_bonus_id_array = {}
|
MMOSimca@460
|
1129 for iterations = 1, num_bonus_ids do
|
MMOSimca@460
|
1130 -- Find minimum of this iteration
|
MMOSimca@460
|
1131 local min_bonus_id = 100000
|
MMOSimca@460
|
1132 for bonus_index = 1, num_bonus_ids do
|
MMOSimca@460
|
1133 local temp_bonus_id = tonumber(item_results[14 + bonus_index])
|
MMOSimca@460
|
1134 if temp_bonus_id and (not min_bonus_id_array[temp_bonus_id]) and (temp_bonus_id < min_bonus_id) then
|
MMOSimca@460
|
1135 min_bonus_id = temp_bonus_id
|
MMOSimca@460
|
1136 end
|
MMOSimca@460
|
1137 end
|
MMOSimca@460
|
1138
|
MMOSimca@460
|
1139 -- Keep track of already processed IDs
|
MMOSimca@460
|
1140 min_bonus_id_array[min_bonus_id] = true
|
MMOSimca@460
|
1141
|
MMOSimca@460
|
1142 -- Build string
|
MMOSimca@460
|
1143 if iterations == 1 then
|
MMOSimca@460
|
1144 sorted_bonus_string = sorted_bonus_string .. tostring(min_bonus_id)
|
MMOSimca@460
|
1145 else
|
MMOSimca@460
|
1146 sorted_bonus_string = sorted_bonus_string .. ":" .. tostring(min_bonus_id)
|
MMOSimca@460
|
1147 end
|
MMOSimca@384
|
1148 end
|
MMOSimca@460
|
1149
|
MMOSimca@460
|
1150 item.seen_bonuses[sorted_bonus_string] = true
|
MMOSimca@460
|
1151 Debug("RecordItemData: Recorded bonus IDs %s for item %d.", sorted_bonus_string, item_id)
|
MMOSimca@384
|
1152 else
|
MMOSimca@460
|
1153 item.seen_bonuses["0"] = true
|
MMOSimca@384
|
1154 end
|
MMOSimca@329
|
1155 end
|
jcallahan@191
|
1156 end
|
jcallahan@0
|
1157 end
|
jcallahan@212
|
1158
|
jcallahan@212
|
1159 if durability and durability > 0 then
|
jcallahan@219
|
1160 item = item or DBEntry("items", item_id)
|
jcallahan@212
|
1161 item.durability = durability
|
jcallahan@212
|
1162 end
|
jcallahan@0
|
1163 end
|
jcallahan@0
|
1164
|
jcallahan@0
|
1165
|
jcallahan@187
|
1166 function WDP:ProcessItems()
|
jcallahan@187
|
1167 for slot_index = _G.INVSLOT_FIRST_EQUIPPED, _G.INVSLOT_LAST_EQUIPPED do
|
jcallahan@1
|
1168 local item_id = _G.GetInventoryItemID("player", slot_index)
|
jcallahan@0
|
1169
|
jcallahan@0
|
1170 if item_id and item_id > 0 then
|
jcallahan@1
|
1171 local _, max_durability = _G.GetInventoryItemDurability(slot_index)
|
MMOSimca@340
|
1172 RecordItemData(item_id, _G.GetInventoryItemLink("player", slot_index), false, max_durability)
|
jcallahan@0
|
1173 end
|
jcallahan@0
|
1174 end
|
jcallahan@0
|
1175
|
jcallahan@0
|
1176 for bag_index = 0, _G.NUM_BAG_SLOTS do
|
MMOSimca@581
|
1177 for slot_index = 1, _G.C_Container.GetContainerNumSlots(bag_index) do
|
MMOSimca@581
|
1178 local item_id = _G.C_Container.GetContainerItemID(bag_index, slot_index)
|
jcallahan@0
|
1179
|
jcallahan@0
|
1180 if item_id and item_id > 0 then
|
MMOSimca@581
|
1181 local _, max_durability = _G.C_Container.GetContainerItemDurability(bag_index, slot_index)
|
MMOSimca@581
|
1182 RecordItemData(item_id, _G.C_Container.GetContainerItemLink(bag_index, slot_index), false, max_durability)
|
jcallahan@0
|
1183 end
|
jcallahan@0
|
1184 end
|
jcallahan@0
|
1185 end
|
jcallahan@0
|
1186 end
|
jcallahan@0
|
1187
|
jcallahan@118
|
1188
|
atcaleb@558
|
1189 local function TargetedNPC()
|
atcaleb@558
|
1190 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or currently_drunk then
|
atcaleb@558
|
1191 current_target_id = nil
|
atcaleb@558
|
1192 return
|
atcaleb@558
|
1193 end
|
atcaleb@558
|
1194 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("target"))
|
atcaleb@558
|
1195
|
atcaleb@558
|
1196 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
atcaleb@558
|
1197 return
|
atcaleb@558
|
1198 end
|
atcaleb@558
|
1199 current_target_id = unit_idnum
|
atcaleb@558
|
1200
|
atcaleb@558
|
1201 local npc = NPCEntry(unit_idnum)
|
atcaleb@558
|
1202 local _, class_token = _G.UnitClass("target")
|
atcaleb@558
|
1203 npc.class = class_token
|
MMOSimca@584
|
1204
|
MMOSimca@584
|
1205 -- Can't do this in instances now, at least using the current method of putting a unit on a tooltip
|
MMOSimca@584
|
1206 if not III() then
|
MMOSimca@584
|
1207 npc.faction = UnitFactionStanding("target")
|
MMOSimca@584
|
1208 end
|
MMOSimca@584
|
1209
|
atcaleb@558
|
1210 npc.genders = npc.genders or {}
|
atcaleb@558
|
1211 npc.genders[private.GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true
|
atcaleb@558
|
1212 npc.is_pvp = _G.UnitIsPVP("target") and true or nil
|
atcaleb@558
|
1213 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), private.REACTION_NAMES[_G.UnitReaction("player", "target")])
|
atcaleb@558
|
1214
|
atcaleb@558
|
1215 local encounter_data = npc:EncounterData(InstanceDifficultyToken()).stats
|
atcaleb@558
|
1216 local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
|
atcaleb@558
|
1217 local level_data = encounter_data[npc_level]
|
atcaleb@558
|
1218
|
atcaleb@558
|
1219 if not level_data then
|
atcaleb@558
|
1220 level_data = {}
|
atcaleb@558
|
1221 encounter_data[npc_level] = level_data
|
atcaleb@558
|
1222 end
|
MMOSimca@583
|
1223
|
MMOSimca@583
|
1224 -- Can't do this in instances now
|
MMOSimca@583
|
1225 if not III() then
|
MMOSimca@583
|
1226 level_data.max_health = level_data.max_health or _G.UnitHealthMax("target")
|
MMOSimca@583
|
1227
|
MMOSimca@583
|
1228 -- May not capture as much data as it could, since the API changed in Legion to report multiple types of power
|
MMOSimca@583
|
1229 if not level_data.power then
|
MMOSimca@583
|
1230 local max_power = _G.UnitPowerMax("target")
|
MMOSimca@583
|
1231
|
MMOSimca@583
|
1232 if max_power > 0 then
|
MMOSimca@583
|
1233 local power_type = _G.UnitPowerType("target")
|
MMOSimca@583
|
1234 level_data.power = ("%s:%d"):format(private.POWER_TYPE_NAMES[tostring(power_type)] or power_type, max_power)
|
MMOSimca@583
|
1235 end
|
jcallahan@118
|
1236 end
|
jcallahan@118
|
1237 end
|
atcaleb@558
|
1238 name_to_id_map[_G.UnitName("target")] = unit_idnum
|
atcaleb@558
|
1239 return npc, unit_idnum
|
atcaleb@558
|
1240 end
|
jcallahan@118
|
1241
|
jcallahan@118
|
1242
|
jcallahan@113
|
1243 do
|
jcallahan@113
|
1244 local COORD_MAX = 5
|
jcallahan@0
|
1245
|
jcallahan@113
|
1246 function WDP:UpdateTargetLocation()
|
catherton@480
|
1247 if currently_drunk or not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or (_G.UnitIsTapDenied("target") and not _G.UnitIsDead("target")) then
|
jcallahan@2
|
1248 return
|
jcallahan@2
|
1249 end
|
jcallahan@113
|
1250
|
jcallahan@113
|
1251 for index = 1, 4 do
|
jcallahan@113
|
1252 if not _G.CheckInteractDistance("target", index) then
|
jcallahan@113
|
1253 return
|
jcallahan@113
|
1254 end
|
jcallahan@113
|
1255 end
|
jcallahan@215
|
1256 local npc = TargetedNPC()
|
jcallahan@113
|
1257
|
jcallahan@113
|
1258 if not npc then
|
jcallahan@113
|
1259 return
|
jcallahan@113
|
1260 end
|
jcallahan@113
|
1261 local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
|
MMOSimca@328
|
1262 if not (zone_name and area_id and x and y and map_level) then
|
mmosimca@508
|
1263 if not (_G.IsInInstance()) then
|
mmosimca@508
|
1264 Debug("UpdateTargetLocation: Missing current location data - %s, %s, %s, %s, %s.", tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
|
mmosimca@508
|
1265 end
|
MMOSimca@328
|
1266 return
|
MMOSimca@328
|
1267 end
|
jcallahan@248
|
1268 local npc_data = npc:EncounterData(difficulty_token).stats[("level_%d"):format(_G.UnitLevel("target"))]
|
jcallahan@113
|
1269 local zone_token = ("%s:%d"):format(zone_name, area_id)
|
jcallahan@118
|
1270 npc_data.locations = npc_data.locations or {} -- TODO: Fix this. It is broken. Possibly something to do with the timed updates.
|
jcallahan@113
|
1271
|
jcallahan@113
|
1272 local zone_data = npc_data.locations[zone_token]
|
jcallahan@113
|
1273
|
jcallahan@113
|
1274 if not zone_data then
|
jcallahan@113
|
1275 zone_data = {}
|
jcallahan@113
|
1276 npc_data.locations[zone_token] = zone_data
|
jcallahan@113
|
1277 end
|
jcallahan@113
|
1278
|
jcallahan@113
|
1279 for location_token in pairs(zone_data) do
|
jcallahan@113
|
1280 local loc_level, loc_x, loc_y = (":"):split(location_token)
|
jcallahan@113
|
1281 loc_level = tonumber(loc_level)
|
jcallahan@113
|
1282
|
jcallahan@113
|
1283 if map_level == loc_level and math.abs(x - loc_x) <= COORD_MAX and math.abs(y - loc_y) <= COORD_MAX then
|
jcallahan@113
|
1284 return
|
jcallahan@113
|
1285 end
|
jcallahan@113
|
1286 end
|
jcallahan@141
|
1287 zone_data[("%d:%d:%d"):format(map_level, x, y)] = true
|
jcallahan@2
|
1288 end
|
jcallahan@113
|
1289 end -- do-block
|
jcallahan@2
|
1290
|
jcallahan@118
|
1291
|
MMOSimca@412
|
1292 function WDP:HandleBadChatLootData(...)
|
MMOSimca@398
|
1293 ClearChatLootData()
|
MMOSimca@398
|
1294 end
|
MMOSimca@398
|
1295
|
MMOSimca@398
|
1296
|
MMOSimca@420
|
1297 -- EVENT HANDLERS -----------------------------------------------------
|
MMOSimca@420
|
1298
|
MMOSimca@436
|
1299 -- This function (and the following function) are to stop 'HandleItemUse' from triggering when you put an item that would normally be opened into the bank, guild bank, etc.
|
MMOSimca@436
|
1300 function WDP:StopChatLootRecording(event_name)
|
MMOSimca@436
|
1301 if not block_chat_loot_data then
|
MMOSimca@439
|
1302 Debug("%s: Pausing chat-based loot recording.", event_name)
|
MMOSimca@436
|
1303 ClearChatLootData()
|
MMOSimca@436
|
1304 block_chat_loot_data = true
|
MMOSimca@436
|
1305 end
|
MMOSimca@436
|
1306 end
|
MMOSimca@436
|
1307
|
MMOSimca@436
|
1308
|
MMOSimca@436
|
1309 function WDP:ResumeChatLootRecording(event_name)
|
MMOSimca@436
|
1310 if block_chat_loot_data then
|
MMOSimca@439
|
1311 Debug("%s: Resuming chat-based loot recording.", event_name)
|
MMOSimca@436
|
1312 block_chat_loot_data = false
|
MMOSimca@436
|
1313 end
|
MMOSimca@436
|
1314 end
|
MMOSimca@436
|
1315
|
MMOSimca@436
|
1316
|
MMOSimca@408
|
1317 -- For now, bonus roll data only pollutes the true drop percentages. We still want to capture the data from SPELL_CONFIRMATION_PROMPT because of legendary quest items though.
|
MMOSimca@408
|
1318 function WDP:BONUS_ROLL_RESULT(event_name)
|
MMOSimca@408
|
1319 Debug("%s: Bonus roll detected; stopping loot recording for this boss to avoid recording bonus loot.", event_name)
|
MMOSimca@408
|
1320 ClearKilledBossID()
|
MMOSimca@408
|
1321 ClearLootToastContainerID()
|
MMOSimca@408
|
1322 end
|
MMOSimca@408
|
1323
|
MMOSimca@408
|
1324
|
atcaleb@573
|
1325 -- Store all known killed NPCs during an island in a table
|
atcaleb@573
|
1326 function WDP:ISLAND_AZERITE_GAIN(event_name, amount, gained_by_player, faction_index, gained_by, gained_from)
|
atcaleb@573
|
1327 -- Exit now if GUID is not for an NPC
|
atcaleb@573
|
1328 local unit_type, unit_id = ParseGUID(gained_from)
|
atcaleb@573
|
1329 if not UnitTypeIsNPC(unit_type) then
|
atcaleb@573
|
1330 return
|
atcaleb@573
|
1331 end
|
atcaleb@573
|
1332
|
atcaleb@573
|
1333 -- Otherwise, store the NPC ID in the island kill table (if it already exists there, increment its count by 1)
|
atcaleb@573
|
1334 Debug("%s: Recording killed island NPC with ID #%d.", event_name, unit_id)
|
atcaleb@573
|
1335 if killed_npcs_in_island[unit_id] then
|
atcaleb@573
|
1336 killed_npcs_in_island[unit_id] = killed_npcs_in_island[unit_id] + 1
|
atcaleb@573
|
1337 else
|
atcaleb@573
|
1338 killed_npcs_in_island[unit_id] = 1
|
atcaleb@573
|
1339 end
|
atcaleb@573
|
1340 end
|
atcaleb@573
|
1341
|
atcaleb@573
|
1342
|
atcaleb@573
|
1343 -- Start chat loot timer for NPCs (and store general island information)
|
atcaleb@573
|
1344 function WDP:ISLAND_COMPLETED(event_name)
|
atcaleb@573
|
1345 island_difficulty_token = InstanceDifficultyToken()
|
atcaleb@573
|
1346
|
atcaleb@573
|
1347 Debug("%s: Beginning chat-based loot timer for Island Expedition rewards.", event_name, item_id)
|
atcaleb@573
|
1348 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
|
atcaleb@573
|
1349 chat_loot_data.category = AF.NPC
|
atcaleb@573
|
1350 chat_loot_data.identifier = 0
|
atcaleb@573
|
1351 end
|
atcaleb@573
|
1352
|
atcaleb@573
|
1353
|
jcallahan@90
|
1354 function WDP:BLACK_MARKET_ITEM_UPDATE(event_name)
|
jcallahan@243
|
1355 if not ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@243
|
1356 return
|
jcallahan@243
|
1357 end
|
jcallahan@282
|
1358 local num_items = _G.C_BlackMarket.GetNumItems() or 0
|
jcallahan@56
|
1359
|
jcallahan@56
|
1360 for index = 1, num_items do
|
jcallahan@56
|
1361 local name, texture, quantity, item_type, is_usable, level, level_type, seller_name, min_bid, min_increment, current_bid, has_high_bid, num_bids, time_left, item_link, market_id = _G.C_BlackMarket.GetItemInfoByIndex(index);
|
jcallahan@56
|
1362
|
jcallahan@56
|
1363 if item_link then
|
jcallahan@56
|
1364 DBEntry("items", ItemLinkToID(item_link)).black_market = seller_name or "UNKNOWN"
|
jcallahan@56
|
1365 end
|
jcallahan@56
|
1366 end
|
jcallahan@56
|
1367 end
|
jcallahan@56
|
1368
|
jcallahan@56
|
1369
|
jcallahan@298
|
1370 local function UpdateUnitPet(unit_guid, unit_id)
|
jcallahan@246
|
1371 local current_pet_guid = group_owner_guids_to_pet_guids[unit_guid]
|
jcallahan@246
|
1372
|
jcallahan@246
|
1373 if current_pet_guid then
|
jcallahan@246
|
1374 group_owner_guids_to_pet_guids[unit_guid] = nil
|
jcallahan@246
|
1375 group_pet_guids[current_pet_guid] = nil
|
jcallahan@246
|
1376 end
|
jcallahan@246
|
1377 local pet_guid = _G.UnitGUID(unit_id .. "pet")
|
jcallahan@246
|
1378
|
jcallahan@246
|
1379 if pet_guid then
|
jcallahan@296
|
1380 group_owner_guids_to_pet_guids[unit_guid] = pet_guid
|
jcallahan@246
|
1381 group_pet_guids[pet_guid] = true
|
jcallahan@246
|
1382 end
|
jcallahan@246
|
1383 end
|
jcallahan@246
|
1384
|
jcallahan@246
|
1385
|
jcallahan@298
|
1386 function WDP:GROUP_ROSTER_UPDATE(event_name)
|
jcallahan@298
|
1387 local is_raid = _G.IsInRaid()
|
jcallahan@298
|
1388 local unit_type = is_raid and "raid" or "party"
|
jcallahan@298
|
1389 local group_size = is_raid and _G.GetNumGroupMembers() or _G.GetNumSubgroupMembers()
|
jcallahan@298
|
1390
|
jcallahan@299
|
1391 table.wipe(group_member_guids)
|
jcallahan@298
|
1392
|
jcallahan@298
|
1393 for index = 1, group_size do
|
jcallahan@298
|
1394 local unit_id = unit_type .. index
|
jcallahan@298
|
1395 local unit_guid = _G.UnitGUID(unit_id)
|
jcallahan@298
|
1396
|
jcallahan@299
|
1397 group_member_guids[unit_guid] = true
|
jcallahan@298
|
1398 UpdateUnitPet(unit_guid, unit_id)
|
jcallahan@298
|
1399 end
|
jcallahan@299
|
1400 group_member_guids[PLAYER_GUID] = true
|
jcallahan@298
|
1401 end
|
jcallahan@298
|
1402
|
jcallahan@298
|
1403
|
jcallahan@298
|
1404 function WDP:UNIT_PET(event_name, unit_id)
|
jcallahan@298
|
1405 UpdateUnitPet(_G.UnitGUID(unit_id), unit_id)
|
jcallahan@298
|
1406 end
|
jcallahan@298
|
1407
|
jcallahan@298
|
1408
|
MMOSimca@375
|
1409 function WDP:SHOW_LOOT_TOAST(event_name, loot_type, item_link, quantity, spec_ID, sex_ID, is_personal, loot_source)
|
jcallahan@312
|
1410 if not loot_type or (loot_type ~= "item" and loot_type ~= "money" and loot_type ~= "currency") then
|
jcallahan@306
|
1411 Debug("%s: loot_type is %s. Item link is %s, and quantity is %d.", event_name, loot_type, item_link, quantity)
|
jcallahan@306
|
1412 return
|
jcallahan@306
|
1413 end
|
MMOSimca@372
|
1414
|
MMOSimca@372
|
1415 -- Need information on the most recent args, so using this complete debug statement for now
|
MMOSimca@375
|
1416 Debug("%s: loot_type: %s, item_link: %s, quantity: %s, spec_ID: %s, sex_ID: %s, is_personal: %s, loot_source: %s", event_name, loot_type, item_link, quantity, spec_ID, sex_ID, is_personal, loot_source)
|
MMOSimca@372
|
1417
|
MMOSimca@355
|
1418 -- Handle Garrison cache specially
|
MMOSimca@422
|
1419 if loot_source and (loot_source == LOOT_SOURCE_ID_GARRISON_CACHE) and last_garrison_cache_object_id then
|
MMOSimca@355
|
1420 -- Record location data for cache
|
MMOSimca@355
|
1421 UpdateDBEntryLocation("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
|
MMOSimca@355
|
1422
|
MMOSimca@355
|
1423 -- Add drop data
|
mmosimca@496
|
1424 local currency_id = CurrencyLinkToID(item_link)
|
mmosimca@496
|
1425 if currency_id and currency_id ~= 0 then
|
MMOSimca@355
|
1426 -- Check for top level object data
|
MMOSimca@355
|
1427 local object_entry = DBEntry("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
|
MMOSimca@355
|
1428 local difficulty_token = InstanceDifficultyToken()
|
MMOSimca@355
|
1429 if object_entry[difficulty_token] then
|
MMOSimca@355
|
1430 -- Increment loot count
|
MMOSimca@355
|
1431 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
|
MMOSimca@355
|
1432
|
mmosimca@496
|
1433 Debug("%s: %d X %d", event_name, currency_id, quantity)
|
MMOSimca@355
|
1434 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
|
mmosimca@496
|
1435 table.insert(object_entry[difficulty_token]["opening"], ("currency:%d:%d"):format(quantity, currency_id))
|
MMOSimca@355
|
1436 else
|
MMOSimca@355
|
1437 Debug("%s: When handling the Garrison cache, the top level loot data was missing for objectID %d.", event_name, last_garrison_cache_object_id)
|
MMOSimca@355
|
1438 end
|
MMOSimca@355
|
1439 else
|
mmosimca@496
|
1440 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
|
MMOSimca@355
|
1441 end
|
catherton@465
|
1442
|
MMOSimca@431
|
1443 -- Wipe object ID until future mouseover
|
MMOSimca@431
|
1444 last_garrison_cache_object_id = nil
|
MMOSimca@387
|
1445 elseif raid_boss_id then
|
MMOSimca@427
|
1446 local npc = NPCEntry(raid_boss_id)
|
MMOSimca@427
|
1447 if npc then
|
MMOSimca@427
|
1448 local loot_label = "drops"
|
MMOSimca@427
|
1449 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
|
MMOSimca@427
|
1450 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
MMOSimca@427
|
1451 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@427
|
1452
|
MMOSimca@427
|
1453 if loot_type == "item" then
|
MMOSimca@427
|
1454 local item_id = ItemLinkToID(item_link)
|
MMOSimca@427
|
1455 if item_id then
|
MMOSimca@427
|
1456 Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
|
MMOSimca@427
|
1457 RecordItemData(item_id, item_link, true)
|
MMOSimca@427
|
1458 table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@427
|
1459 else
|
MMOSimca@427
|
1460 Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
|
MMOSimca@427
|
1461 return
|
MMOSimca@427
|
1462 end
|
MMOSimca@427
|
1463 elseif loot_type == "money" then
|
MMOSimca@427
|
1464 Debug("%s: money X %d", event_name, quantity)
|
MMOSimca@427
|
1465 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
MMOSimca@427
|
1466 elseif loot_type == "currency" then
|
mmosimca@496
|
1467 local currency_id = CurrencyLinkToID(item_link)
|
mmosimca@496
|
1468 if currency_id and currency_id ~= 0 then
|
mmosimca@496
|
1469 Debug("%s: %d X %d", event_name, currency_id, quantity)
|
mmosimca@496
|
1470 table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
|
MMOSimca@427
|
1471 else
|
mmosimca@496
|
1472 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
|
MMOSimca@427
|
1473 return
|
MMOSimca@427
|
1474 end
|
jcallahan@312
|
1475 end
|
jcallahan@317
|
1476
|
MMOSimca@427
|
1477 if not boss_loot_toasting[raid_boss_id] then
|
MMOSimca@427
|
1478 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
MMOSimca@427
|
1479 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
|
jcallahan@312
|
1480 end
|
jcallahan@312
|
1481 end
|
MMOSimca@387
|
1482 elseif loot_toast_container_id then
|
jcallahan@305
|
1483 InitializeCurrentLoot()
|
jcallahan@305
|
1484
|
jcallahan@306
|
1485 -- Fake the loot characteristics to match that of an actual container item
|
MMOSimca@387
|
1486 current_loot.identifier = loot_toast_container_id
|
jcallahan@306
|
1487 current_loot.label = "contains"
|
jcallahan@306
|
1488 current_loot.target_type = AF.ITEM
|
jcallahan@306
|
1489
|
MMOSimca@387
|
1490 current_loot.sources[loot_toast_container_id] = current_loot.sources[loot_toast_container_id] or {}
|
jcallahan@312
|
1491
|
jcallahan@301
|
1492 if loot_type == "item" then
|
jcallahan@312
|
1493 local item_id = ItemLinkToID(item_link)
|
jcallahan@312
|
1494 if item_id then
|
jcallahan@312
|
1495 Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
|
MMOSimca@340
|
1496 RecordItemData(item_id, item_link, true)
|
MMOSimca@387
|
1497 current_loot.sources[loot_toast_container_id][item_id] = (current_loot.sources[loot_toast_container_id][item_id] or 0) + quantity
|
jcallahan@312
|
1498 else
|
jcallahan@301
|
1499 Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
|
jcallahan@312
|
1500 current_loot = nil
|
jcallahan@301
|
1501 return
|
jcallahan@301
|
1502 end
|
jcallahan@301
|
1503 elseif loot_type == "money" then
|
jcallahan@312
|
1504 Debug("%s: money X %d", event_name, quantity)
|
MMOSimca@387
|
1505 current_loot.sources[loot_toast_container_id]["money"] = (current_loot.sources[loot_toast_container_id]["money"] or 0) + quantity
|
jcallahan@312
|
1506 elseif loot_type == "currency" then
|
mmosimca@496
|
1507 local currency_id = CurrencyLinkToID(item_link)
|
mmosimca@496
|
1508 if currency_id and currency_id ~= 0 then
|
mmosimca@496
|
1509 Debug("%s: %d X %d", event_name, currency_id, quantity)
|
mmosimca@496
|
1510 local currency_token = ("currency:%d"):format(currency_id)
|
MMOSimca@387
|
1511 current_loot.sources[loot_toast_container_id][currency_token] = (current_loot.sources[loot_toast_container_id][currency_token] or 0) + quantity
|
jcallahan@312
|
1512 else
|
mmosimca@496
|
1513 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
|
jcallahan@312
|
1514 current_loot = nil
|
jcallahan@312
|
1515 return
|
jcallahan@312
|
1516 end
|
jcallahan@301
|
1517 end
|
jcallahan@312
|
1518
|
jcallahan@301
|
1519 GenericLootUpdate("items")
|
jcallahan@301
|
1520 current_loot = nil
|
MMOSimca@387
|
1521 container_loot_toasting = true -- Do not count further loots until timer expires or another container is opened
|
atcaleb@573
|
1522 elseif loot_source and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
|
MMOSimca@444
|
1523 -- Handle currency loot toasts for chat-based loot (we do this instead of reading currency chat messages because the chat messages are very delayed)
|
MMOSimca@444
|
1524 if loot_type == "currency" then
|
mmosimca@496
|
1525 local currency_id = CurrencyLinkToID(item_link)
|
mmosimca@496
|
1526 if currency_id and currency_id ~= 0 then
|
MMOSimca@444
|
1527 -- Verify that we're still assigning data to the right items
|
atcaleb@573
|
1528 if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
mmosimca@496
|
1529 Debug("%s: Captured currency for chat-based loot recording. %d X %d", event_name, currency_id, quantity)
|
mmosimca@496
|
1530 local currency_token = ("currency:%d"):format(currency_id)
|
MMOSimca@444
|
1531 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@444
|
1532 chat_loot_data.loot[currency_token] = (chat_loot_data.loot[currency_token] or 0) + quantity
|
MMOSimca@444
|
1533 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@444
|
1534 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
|
MMOSimca@444
|
1535 ClearChatLootData()
|
MMOSimca@444
|
1536 end
|
MMOSimca@444
|
1537 else
|
mmosimca@496
|
1538 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
|
MMOSimca@444
|
1539 end
|
MMOSimca@444
|
1540 -- Handle money loot toasts for chat-based loot (we do this instead of reading money chat messages because the chat messages are very delayed)
|
MMOSimca@444
|
1541 elseif loot_type == "money" then
|
MMOSimca@424
|
1542 -- Verify that we're still assigning data to the right items
|
atcaleb@573
|
1543 if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
MMOSimca@444
|
1544 Debug("%s: Captured money for chat-based loot recording. money X %d", event_name, quantity)
|
MMOSimca@435
|
1545 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@444
|
1546 chat_loot_data.loot["money"] = (chat_loot_data.loot["money"] or 0) + quantity
|
MMOSimca@424
|
1547 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@424
|
1548 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
|
MMOSimca@424
|
1549 ClearChatLootData()
|
MMOSimca@424
|
1550 end
|
MMOSimca@424
|
1551 end
|
jcallahan@301
|
1552 else
|
jcallahan@307
|
1553 Debug("%s: NPC and Container are nil, storing loot toast data for 5 seconds.", event_name)
|
jcallahan@307
|
1554
|
jcallahan@307
|
1555 loot_toast_data = loot_toast_data or {}
|
jcallahan@312
|
1556 loot_toast_data[#loot_toast_data + 1] = { loot_type, item_link, quantity }
|
jcallahan@307
|
1557
|
MMOSimca@340
|
1558 local item_id = ItemLinkToID(item_link)
|
MMOSimca@340
|
1559 if item_id then
|
MMOSimca@340
|
1560 RecordItemData(item_id, item_link, true)
|
MMOSimca@340
|
1561 end
|
MMOSimca@340
|
1562
|
MMOSimca@383
|
1563 loot_toast_data_timer_handle = C_Timer.NewTimer(5, ClearLootToastData)
|
jcallahan@178
|
1564 end
|
jcallahan@178
|
1565 end
|
jcallahan@178
|
1566
|
jcallahan@178
|
1567
|
jcallahan@179
|
1568 do
|
MMOSimca@388
|
1569 local CHAT_MSG_CURRENCY_UPDATE_FUNCS = {
|
mmosimca@496
|
1570 [AF.NPC] = function(currency_id, quantity)
|
mmosimca@496
|
1571 Debug("CHAT_MSG_CURRENCY: AF.NPC currency:%d (%d)", currency_id, quantity)
|
MMOSimca@388
|
1572 end,
|
mmosimca@496
|
1573 [AF.ZONE] = function(currency_id, quantity)
|
mmosimca@496
|
1574 Debug("CHAT_MSG_CURRENCY: AF.ZONE currency:%d (%d)", currency_id, quantity)
|
MMOSimca@388
|
1575 InitializeCurrentLoot()
|
mmosimca@496
|
1576 current_loot.list[1] = ("currency:%d:%d"):format(quantity, currency_id)
|
MMOSimca@388
|
1577 GenericLootUpdate("zones")
|
MMOSimca@388
|
1578 current_loot = nil
|
MMOSimca@388
|
1579 end,
|
MMOSimca@388
|
1580 }
|
MMOSimca@388
|
1581
|
MMOSimca@388
|
1582
|
MMOSimca@388
|
1583 function WDP:CHAT_MSG_CURRENCY(event_name, message)
|
MMOSimca@388
|
1584 local category
|
MMOSimca@388
|
1585
|
MMOSimca@388
|
1586 local currency_link, quantity = deformat(message, _G.CURRENCY_GAINED_MULTIPLE)
|
MMOSimca@388
|
1587 if not currency_link then
|
MMOSimca@388
|
1588 quantity, currency_link = 1, deformat(message, _G.CURRENCY_GAINED)
|
MMOSimca@388
|
1589 end
|
mmosimca@496
|
1590 local currency_id = CurrencyLinkToID(currency_link)
|
mmosimca@496
|
1591
|
mmosimca@496
|
1592 if not currency_id or currency_id == 0 then
|
MMOSimca@388
|
1593 return
|
MMOSimca@388
|
1594 end
|
MMOSimca@388
|
1595
|
MMOSimca@388
|
1596 -- Set update category
|
MMOSimca@388
|
1597 if current_action.spell_label == "FISHING" then
|
MMOSimca@388
|
1598 category = AF.ZONE
|
MMOSimca@388
|
1599 elseif raid_boss_id then
|
MMOSimca@388
|
1600 category = AF.NPC
|
MMOSimca@388
|
1601 end
|
MMOSimca@388
|
1602
|
MMOSimca@388
|
1603 -- Take action based on update category
|
MMOSimca@388
|
1604 local update_func = CHAT_MSG_CURRENCY_UPDATE_FUNCS[category]
|
MMOSimca@388
|
1605 if not category or not update_func then
|
MMOSimca@388
|
1606 return
|
MMOSimca@388
|
1607 end
|
mmosimca@496
|
1608 update_func(currency_id, quantity)
|
MMOSimca@388
|
1609 end
|
MMOSimca@388
|
1610
|
MMOSimca@388
|
1611
|
jcallahan@179
|
1612 local CHAT_MSG_LOOT_UPDATE_FUNCS = {
|
atcaleb@573
|
1613 -- Handle chat loot data from item containers
|
MMOSimca@347
|
1614 [AF.ITEM] = function(item_id, quantity)
|
MMOSimca@347
|
1615 -- Verify that we're still assigning data to the right items
|
MMOSimca@435
|
1616 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
MMOSimca@347
|
1617 Debug("CHAT_MSG_LOOT: AF.ITEM %d (%d)", item_id, quantity)
|
MMOSimca@435
|
1618 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@435
|
1619 chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
|
MMOSimca@347
|
1620 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@387
|
1621 Debug("CHAT_MSG_LOOT: We would have assigned the wrong loot!")
|
MMOSimca@387
|
1622 ClearChatLootData()
|
MMOSimca@347
|
1623 end
|
MMOSimca@347
|
1624 end,
|
atcaleb@573
|
1625 -- Handle chat loot data from island expedition rewards
|
jcallahan@179
|
1626 [AF.NPC] = function(item_id, quantity)
|
MMOSimca@345
|
1627 Debug("CHAT_MSG_LOOT: AF.NPC %d (%d)", item_id, quantity)
|
atcaleb@573
|
1628 chat_loot_data.loot = chat_loot_data.loot or {}
|
atcaleb@573
|
1629 chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
|
MMOSimca@345
|
1630 end,
|
atcaleb@573
|
1631 -- Handle logging spells for objects
|
MMOSimca@345
|
1632 [AF.OBJECT] = function(item_id, quantity)
|
MMOSimca@345
|
1633 Debug("CHAT_MSG_LOOT: AF.OBJECT %d (%d)", item_id, quantity)
|
MMOSimca@381
|
1634 -- Check for top level object data
|
MMOSimca@381
|
1635 local object_entry = DBEntry("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id]))
|
MMOSimca@381
|
1636 local difficulty_token = InstanceDifficultyToken()
|
MMOSimca@381
|
1637 if object_entry[difficulty_token] then
|
MMOSimca@381
|
1638 -- Increment loot count
|
MMOSimca@381
|
1639 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
|
MMOSimca@381
|
1640
|
MMOSimca@381
|
1641 -- Add drop data
|
MMOSimca@381
|
1642 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
|
MMOSimca@381
|
1643 table.insert(object_entry[difficulty_token]["opening"], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@381
|
1644 else
|
MMOSimca@381
|
1645 Debug("CHAT_MSG_LOOT: When handling timber, the top level data was missing for objectID %s.", private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id])
|
MMOSimca@381
|
1646 end
|
jcallahan@179
|
1647 end,
|
atcaleb@573
|
1648 -- Handle fishing loot table population
|
jcallahan@179
|
1649 [AF.ZONE] = function(item_id, quantity)
|
MMOSimca@345
|
1650 Debug("CHAT_MSG_LOOT: AF.ZONE %d (%d)", item_id, quantity)
|
jcallahan@312
|
1651 InitializeCurrentLoot()
|
jcallahan@312
|
1652 current_loot.list[1] = ("%d:%d"):format(item_id, quantity)
|
jcallahan@179
|
1653 GenericLootUpdate("zones")
|
jcallahan@312
|
1654 current_loot = nil
|
jcallahan@179
|
1655 end,
|
jcallahan@179
|
1656 }
|
jcallahan@177
|
1657
|
jcallahan@177
|
1658
|
MMOSimca@388
|
1659 function WDP:CHAT_MSG_LOOT(event_name, message)
|
jcallahan@179
|
1660 local category
|
jcallahan@177
|
1661
|
MMOSimca@345
|
1662 local item_link, quantity = deformat(message, _G.LOOT_ITEM_PUSHED_SELF_MULTIPLE)
|
MMOSimca@345
|
1663 if not item_link then
|
MMOSimca@345
|
1664 quantity, item_link = 1, deformat(message, _G.LOOT_ITEM_PUSHED_SELF)
|
MMOSimca@345
|
1665 end
|
MMOSimca@345
|
1666 local item_id = ItemLinkToID(item_link)
|
MMOSimca@345
|
1667
|
MMOSimca@345
|
1668 if not item_id then
|
MMOSimca@345
|
1669 return
|
MMOSimca@345
|
1670 end
|
MMOSimca@345
|
1671
|
MMOSimca@345
|
1672 -- Set update category
|
MMOSimca@405
|
1673 if last_timber_spell_id and item_id == ITEM_ID_TIMBER then
|
MMOSimca@345
|
1674 category = AF.OBJECT
|
atcaleb@573
|
1675 -- Changed from ~= "EXTRACT_GAS" because of some occassional bad data, and, as far as I know, no benefit.
|
MMOSimca@345
|
1676 elseif current_action.spell_label == "FISHING" then
|
jcallahan@179
|
1677 category = AF.ZONE
|
atcaleb@573
|
1678 elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.NPC then
|
jcallahan@179
|
1679 category = AF.NPC
|
atcaleb@573
|
1680 elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
|
MMOSimca@347
|
1681 category = AF.ITEM
|
jcallahan@179
|
1682 end
|
MMOSimca@345
|
1683
|
MMOSimca@395
|
1684 -- We still want to record the item's data, even if it doesn't need its drop location recorded
|
MMOSimca@395
|
1685 RecordItemData(item_id, item_link, true)
|
MMOSimca@395
|
1686
|
MMOSimca@345
|
1687 -- Take action based on update category
|
jcallahan@179
|
1688 local update_func = CHAT_MSG_LOOT_UPDATE_FUNCS[category]
|
atcaleb@558
|
1689 if not category or not update_func or private.BLACKLISTED_ITEMS[item_id] then
|
MMOSimca@340
|
1690 return
|
MMOSimca@340
|
1691 end
|
jcallahan@179
|
1692 update_func(item_id, quantity)
|
jcallahan@177
|
1693 end
|
MMOSimca@388
|
1694 end
|
MMOSimca@388
|
1695
|
MMOSimca@388
|
1696
|
jcallahan@97
|
1697 function WDP:RecordQuote(event_name, message, source_name, language_name)
|
jcallahan@112
|
1698 if not ALLOWED_LOCALES[CLIENT_LOCALE] or not source_name or not name_to_id_map[source_name] or (language_name ~= "" and not languages_known[language_name]) then
|
jcallahan@97
|
1699 return
|
jcallahan@95
|
1700 end
|
jcallahan@97
|
1701 local npc = NPCEntry(name_to_id_map[source_name])
|
jcallahan@97
|
1702 npc.quotes = npc.quotes or {}
|
jcallahan@97
|
1703 npc.quotes[event_name] = npc.quotes[event_name] or {}
|
jcallahan@97
|
1704 npc.quotes[event_name][ReplaceKeywords(message)] = true
|
jcallahan@97
|
1705 end
|
jcallahan@95
|
1706
|
jcallahan@95
|
1707
|
jcallahan@95
|
1708 do
|
jcallahan@40
|
1709 local SOBER_MATCH = _G.DRUNK_MESSAGE_ITEM_SELF1:gsub("%%s", ".+")
|
jcallahan@40
|
1710
|
jcallahan@40
|
1711 local DRUNK_COMPARES = {
|
jcallahan@40
|
1712 _G.DRUNK_MESSAGE_SELF2,
|
jcallahan@40
|
1713 _G.DRUNK_MESSAGE_SELF3,
|
jcallahan@40
|
1714 _G.DRUNK_MESSAGE_SELF4,
|
jcallahan@40
|
1715 }
|
jcallahan@40
|
1716
|
jcallahan@40
|
1717 local DRUNK_MATCHES = {
|
jcallahan@254
|
1718 (_G.DRUNK_MESSAGE_SELF2:gsub("%%s", ".+")),
|
jcallahan@254
|
1719 (_G.DRUNK_MESSAGE_SELF3:gsub("%%s", ".+")),
|
jcallahan@254
|
1720 (_G.DRUNK_MESSAGE_SELF4:gsub("%%s", ".+")),
|
jcallahan@40
|
1721 }
|
jcallahan@40
|
1722
|
jcallahan@167
|
1723 local RECIPE_MATCH = _G.ERR_LEARN_RECIPE_S:gsub("%%s", "(.*)")
|
jcallahan@167
|
1724
|
jcallahan@167
|
1725
|
jcallahan@167
|
1726 local function RecordDiscovery(tradeskill_name, tradeskill_index)
|
jcallahan@167
|
1727 if tradeskill_name == private.discovered_recipe_name then
|
catherton@479
|
1728 DBEntry("spells", tonumber(_G.C_TradeSkillUI.GetRecipeLink(tradeskill_index):match("^|c%x%x%x%x%x%x%x%x|H%w+:(%d+)"))).discovery = ("%d:%d"):format(private.previous_spell_id, private.profession_level)
|
jcallahan@167
|
1729
|
jcallahan@167
|
1730 private.discovered_recipe_name = nil
|
jcallahan@167
|
1731 private.profession_level = nil
|
jcallahan@167
|
1732 private.previous_spell_id = nil
|
jcallahan@169
|
1733
|
jcallahan@169
|
1734 return true
|
jcallahan@167
|
1735 end
|
jcallahan@167
|
1736 end
|
jcallahan@167
|
1737
|
jcallahan@167
|
1738
|
jcallahan@167
|
1739 local function IterativeRecordDiscovery()
|
jcallahan@167
|
1740 TradeSkillExecutePer(RecordDiscovery)
|
jcallahan@167
|
1741 end
|
jcallahan@167
|
1742
|
jcallahan@167
|
1743
|
jcallahan@92
|
1744 function WDP:CHAT_MSG_SYSTEM(event_name, message)
|
mmosimca@514
|
1745 -- This code no longer works, as of Patch 7.0.3, because Blizzard unified the text from quest rewards and loot to match (and now there is no way to distinguish between them)
|
MMOSimca@532
|
1746 --[[
|
MMOSimca@532
|
1747 -- Removed in Patch 7.0.3; previously used to determine if a system message was a quest reward or not
|
MMOSimca@532
|
1748 local ERR_QUEST_REWARD_ITEM_MULT_IS = _G.ERR_QUEST_REWARD_ITEM_MULT_IS or "Received %d of item: %s."
|
MMOSimca@532
|
1749 local ERR_QUEST_REWARD_ITEM_S = _G.ERR_QUEST_REWARD_ITEM_S or "Received item: %s."
|
MMOSimca@532
|
1750
|
catherton@472
|
1751 local item_link, quantity = deformat(message, ERR_QUEST_REWARD_ITEM_MULT_IS)
|
MMOSimca@400
|
1752 if not item_link then
|
catherton@472
|
1753 quantity, item_link = 1, deformat(message, ERR_QUEST_REWARD_ITEM_S)
|
MMOSimca@400
|
1754 end
|
MMOSimca@400
|
1755 local item_id = ItemLinkToID(item_link)
|
MMOSimca@400
|
1756
|
mmosimca@514
|
1757 if item_id then
|
mmosimca@514
|
1758 -- If it was a quest message (that we can decode), parse its link
|
mmosimca@514
|
1759 RecordItemData(item_id, item_link, true)
|
mmosimca@514
|
1760 else
|
mmosimca@514
|
1761 -- If it isn't a quest message, check the other uses of system messages
|
MMOSimca@532
|
1762 end
|
MMOSimca@532
|
1763 ]]--
|
MMOSimca@532
|
1764
|
MMOSimca@532
|
1765 if not private.trainer_shown then
|
MMOSimca@532
|
1766 local recipe_name = message:match(RECIPE_MATCH)
|
MMOSimca@532
|
1767
|
MMOSimca@532
|
1768 if recipe_name and private.previous_spell_id then
|
MMOSimca@532
|
1769 local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
|
MMOSimca@532
|
1770
|
MMOSimca@532
|
1771 if profession_name == _G.UNKNOWN then
|
MMOSimca@532
|
1772 return
|
jcallahan@167
|
1773 end
|
MMOSimca@532
|
1774 private.discovered_recipe_name = recipe_name
|
MMOSimca@532
|
1775 private.profession_level = prof_level
|
MMOSimca@532
|
1776
|
MMOSimca@532
|
1777 C_Timer.After(0.2, IterativeRecordDiscovery)
|
jcallahan@167
|
1778 end
|
MMOSimca@532
|
1779 end
|
MMOSimca@532
|
1780
|
MMOSimca@532
|
1781 if currently_drunk then
|
MMOSimca@532
|
1782 if message == _G.DRUNK_MESSAGE_SELF1 or message:match(SOBER_MATCH) then
|
MMOSimca@532
|
1783 currently_drunk = nil
|
MMOSimca@400
|
1784 end
|
MMOSimca@532
|
1785 return
|
MMOSimca@532
|
1786 end
|
MMOSimca@532
|
1787
|
MMOSimca@532
|
1788 for index = 1, #DRUNK_MATCHES do
|
MMOSimca@532
|
1789 if message == DRUNK_COMPARES[index] or message:match(DRUNK_MATCHES[index]) then
|
MMOSimca@532
|
1790 currently_drunk = true
|
MMOSimca@532
|
1791 break
|
jcallahan@40
|
1792 end
|
jcallahan@40
|
1793 end
|
jcallahan@40
|
1794 end
|
jcallahan@40
|
1795 end
|
jcallahan@40
|
1796
|
jcallahan@307
|
1797
|
MMOSimca@581
|
1798 function WDP:WORLD_CURSOR_TOOLTIP_UPDATE(event_name, is_shown)
|
MMOSimca@355
|
1799 if current_action.fishing_target or _G.Minimap:IsMouseOver() then
|
jcallahan@140
|
1800 return
|
jcallahan@140
|
1801 end
|
jcallahan@140
|
1802 local text = _G["GameTooltipTextLeft1"]:GetText()
|
jcallahan@140
|
1803
|
MMOSimca@355
|
1804 -- Handle Fishing
|
MMOSimca@355
|
1805 if (current_action.spell_label == "FISHING") then
|
MMOSimca@355
|
1806 if not text or text == "Fishing Bobber" then
|
MMOSimca@355
|
1807 text = "NONE"
|
MMOSimca@355
|
1808 else
|
MMOSimca@355
|
1809 current_action.fishing_target = true
|
MMOSimca@355
|
1810 end
|
MMOSimca@355
|
1811 current_action.identifier = ("%s:%s"):format(current_action.spell_label, text)
|
MMOSimca@355
|
1812 -- Handle Garrison Cache
|
MMOSimca@355
|
1813 elseif private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text] then
|
MMOSimca@355
|
1814 last_garrison_cache_object_id = private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text]
|
jcallahan@140
|
1815 end
|
jcallahan@140
|
1816 end
|
jcallahan@140
|
1817
|
jcallahan@140
|
1818
|
jcallahan@92
|
1819 function WDP:ITEM_TEXT_BEGIN(event_name)
|
jcallahan@42
|
1820 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@42
|
1821
|
jcallahan@42
|
1822 if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT or _G.UnitName("npc") ~= _G.ItemTextGetItem() then
|
jcallahan@42
|
1823 return
|
jcallahan@42
|
1824 end
|
jcallahan@42
|
1825 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@42
|
1826 end
|
jcallahan@42
|
1827
|
jcallahan@42
|
1828
|
jcallahan@13
|
1829 do
|
MMOSimca@343
|
1830 local LOOT_OPENED_VERIFY_FUNCS = {
|
jcallahan@324
|
1831 -- Item containers can be AOE-looted in Patch 5.4.2 if the user clicks fast enough, but this verification still works as long as they both have loot.
|
jcallahan@16
|
1832 [AF.ITEM] = function()
|
jcallahan@16
|
1833 local locked_item_id
|
jcallahan@16
|
1834
|
jcallahan@16
|
1835 for bag_index = 0, _G.NUM_BAG_FRAMES do
|
MMOSimca@581
|
1836 for slot_index = 1, _G.C_Container.GetContainerNumSlots(bag_index) do
|
MMOSimca@581
|
1837 local _, _, is_locked, _, _, is_lootable = _G.C_Container.GetContainerItemInfo(bag_index, slot_index)
|
jcallahan@324
|
1838
|
jcallahan@324
|
1839 if is_locked and is_lootable then
|
MMOSimca@581
|
1840 locked_item_id = ItemLinkToID(_G.C_Container.GetContainerItemLink(bag_index, slot_index))
|
jcallahan@165
|
1841 break
|
jcallahan@16
|
1842 end
|
jcallahan@16
|
1843 end
|
jcallahan@165
|
1844
|
jcallahan@165
|
1845 if locked_item_id then
|
jcallahan@165
|
1846 break
|
jcallahan@165
|
1847 end
|
jcallahan@16
|
1848 end
|
jcallahan@16
|
1849
|
MMOSimca@367
|
1850 if (not current_action.spell_label == "DISENCHANT") and (not locked_item_id or (current_action.identifier and current_action.identifier ~= locked_item_id)) then
|
jcallahan@16
|
1851 return false
|
jcallahan@16
|
1852 end
|
jcallahan@122
|
1853 current_action.identifier = locked_item_id
|
jcallahan@16
|
1854 return true
|
jcallahan@16
|
1855 end,
|
MMOSimca@401
|
1856 [AF.NPC] = function()
|
MMOSimca@401
|
1857 return not _G.IsFishingLoot()
|
MMOSimca@401
|
1858 end,
|
MMOSimca@401
|
1859 [AF.OBJECT] = function()
|
MMOSimca@401
|
1860 return not _G.IsFishingLoot()
|
MMOSimca@401
|
1861 end,
|
jcallahan@17
|
1862 [AF.ZONE] = function()
|
jcallahan@140
|
1863 current_action.zone_data = UpdateDBEntryLocation("zones", current_action.identifier)
|
jcallahan@210
|
1864 return _G.IsFishingLoot()
|
jcallahan@17
|
1865 end,
|
jcallahan@13
|
1866 }
|
jcallahan@13
|
1867
|
jcallahan@13
|
1868
|
MMOSimca@343
|
1869 local LOOT_OPENED_UPDATE_FUNCS = {
|
jcallahan@16
|
1870 [AF.ITEM] = function()
|
jcallahan@28
|
1871 GenericLootUpdate("items")
|
jcallahan@28
|
1872 end,
|
jcallahan@28
|
1873 [AF.NPC] = function()
|
jcallahan@75
|
1874 local difficulty_token = InstanceDifficultyToken()
|
jcallahan@312
|
1875 local loot_label = current_loot.label
|
jcallahan@77
|
1876 local source_list = {}
|
jcallahan@75
|
1877
|
jcallahan@131
|
1878 for source_guid, loot_data in pairs(current_loot.sources) do
|
jcallahan@331
|
1879 local _, source_id = ParseGUID(source_guid)
|
jcallahan@75
|
1880 local npc = NPCEntry(source_id)
|
jcallahan@75
|
1881
|
jcallahan@75
|
1882 if npc then
|
jcallahan@248
|
1883 local encounter_data = npc:EncounterData(difficulty_token)
|
jcallahan@312
|
1884 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
jcallahan@75
|
1885
|
jcallahan@78
|
1886 if not source_list[source_guid] then
|
jcallahan@77
|
1887 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@426
|
1888 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
jcallahan@312
|
1889 source_list[source_guid] = true
|
jcallahan@77
|
1890 end
|
jcallahan@77
|
1891
|
jcallahan@309
|
1892 for loot_token, quantity in pairs(loot_data) do
|
mmosimca@496
|
1893 local loot_type, currency_id = (":"):split(loot_token)
|
mmosimca@496
|
1894
|
mmosimca@496
|
1895 if loot_type == "currency" and currency_id then
|
mmosimca@496
|
1896 -- Convert currency_id back into number from string
|
mmosimca@496
|
1897 currency_id = tonumber(currency_id) or 0
|
mmosimca@496
|
1898 if currency_id ~= 0 then
|
mmosimca@496
|
1899 table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
|
mmosimca@496
|
1900 end
|
jcallahan@309
|
1901 elseif loot_token == "money" then
|
jcallahan@312
|
1902 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
jcallahan@309
|
1903 else
|
jcallahan@312
|
1904 table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
|
jcallahan@309
|
1905 end
|
jcallahan@75
|
1906 end
|
jcallahan@75
|
1907 end
|
jcallahan@75
|
1908 end
|
jcallahan@16
|
1909 end,
|
jcallahan@13
|
1910 [AF.OBJECT] = function()
|
jcallahan@28
|
1911 GenericLootUpdate("objects", InstanceDifficultyToken())
|
jcallahan@17
|
1912 end,
|
jcallahan@17
|
1913 [AF.ZONE] = function()
|
MMOSimca@328
|
1914 if not (current_loot.map_level and current_loot.x and current_loot.y and current_loot.zone_data) then
|
MMOSimca@328
|
1915 return
|
MMOSimca@328
|
1916 end
|
jcallahan@141
|
1917 local location_token = ("%d:%d:%d"):format(current_loot.map_level, current_loot.x, current_loot.y)
|
jcallahan@41
|
1918
|
jcallahan@41
|
1919 -- This will start life as a boolean true.
|
mmosimca@522
|
1920 if type(current_loot.zone_data[location_token]) ~= "table" then
|
jcallahan@131
|
1921 current_loot.zone_data[location_token] = {
|
jcallahan@41
|
1922 drops = {}
|
jcallahan@41
|
1923 }
|
jcallahan@41
|
1924 end
|
jcallahan@132
|
1925 local loot_count = ("%s_count"):format(current_loot.label)
|
jcallahan@131
|
1926 current_loot.zone_data[location_token][loot_count] = (current_loot.zone_data[location_token][loot_count] or 0) + 1
|
jcallahan@41
|
1927
|
jcallahan@131
|
1928 if current_loot.sources then
|
jcallahan@131
|
1929 for source_guid, loot_data in pairs(current_loot.sources) do
|
jcallahan@131
|
1930 for item_id, quantity in pairs(loot_data) do
|
jcallahan@131
|
1931 table.insert(current_loot.zone_data[location_token].drops, ("%d:%d"):format(item_id, quantity))
|
jcallahan@131
|
1932 end
|
jcallahan@131
|
1933 end
|
jcallahan@131
|
1934 end
|
jcallahan@131
|
1935
|
jcallahan@131
|
1936 if #current_loot.list <= 0 then
|
jcallahan@131
|
1937 return
|
jcallahan@131
|
1938 end
|
jcallahan@131
|
1939
|
jcallahan@131
|
1940 for index = 1, #current_loot.list do
|
MMOSimca@443
|
1941 table.insert(current_loot.zone_data[location_token].drops, current_loot.list[index])
|
jcallahan@41
|
1942 end
|
jcallahan@13
|
1943 end,
|
jcallahan@13
|
1944 }
|
jcallahan@13
|
1945
|
jcallahan@79
|
1946 -- Prevent opening the same loot window multiple times from recording data multiple times.
|
jcallahan@79
|
1947 local loot_guid_registry = {}
|
jcallahan@124
|
1948
|
jcallahan@124
|
1949
|
jcallahan@124
|
1950 function WDP:LOOT_CLOSED(event_name)
|
MMOSimca@398
|
1951 ClearChatLootData()
|
jcallahan@131
|
1952 current_loot = nil
|
jcallahan@131
|
1953 table.wipe(current_action)
|
jcallahan@124
|
1954 end
|
jcallahan@124
|
1955
|
jcallahan@13
|
1956
|
jcallahan@322
|
1957 local function ExtrapolatedCurrentActionFromLootData(event_name)
|
MMOSimca@402
|
1958 local log_source = event_name .. "- ExtrapolatedCurrentActionFromLootData"
|
MMOSimca@402
|
1959 local previous_spell_label = current_action.spell_label
|
jcallahan@322
|
1960 local extrapolated_guid_registry = {}
|
jcallahan@322
|
1961 local num_guids = 0
|
MMOSimca@402
|
1962 table.wipe(current_action)
|
MMOSimca@402
|
1963
|
MMOSimca@402
|
1964 if _G.IsFishingLoot() then
|
MMOSimca@402
|
1965 -- Set up a proper 'fishing' current_action table
|
MMOSimca@402
|
1966 local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
|
MMOSimca@402
|
1967 if not (zone_name and area_id and x and y and map_level) then
|
mmosimca@508
|
1968 if not (_G.IsInInstance()) then
|
mmosimca@508
|
1969 Debug("%s: Missing current location data - %s, %s, %s, %s, %s.", log_source, tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
|
mmosimca@508
|
1970 end
|
MMOSimca@402
|
1971 return
|
MMOSimca@402
|
1972 end
|
MMOSimca@402
|
1973 current_action.instance_token = instance_token
|
MMOSimca@402
|
1974 current_action.map_level = map_level
|
MMOSimca@402
|
1975 current_action.x = x
|
MMOSimca@402
|
1976 current_action.y = y
|
MMOSimca@402
|
1977 current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
|
MMOSimca@402
|
1978 current_action.spell_label = "FISHING"
|
MMOSimca@402
|
1979 current_action.loot_label = "fishing"
|
MMOSimca@402
|
1980 current_action.identifier = "FISHING:NONE"
|
MMOSimca@402
|
1981 current_action.target_type = AF.ZONE
|
MMOSimca@402
|
1982
|
MMOSimca@402
|
1983 Debug("%s: Fishing loot detected.", log_source)
|
MMOSimca@402
|
1984 return true
|
MMOSimca@402
|
1985 end
|
jcallahan@322
|
1986
|
MMOSimca@344
|
1987 -- Loot extrapolation cannot handle objects that need special spell labels (like HERBALISM or MINING) (MIND_CONTROL is okay)
|
MMOSimca@402
|
1988 if previous_spell_label and private.SPELL_FLAGS_BY_LABEL[previous_spell_label] and not private.NON_LOOT_SPELL_LABELS[previous_spell_label] then
|
MMOSimca@344
|
1989 Debug("%s: Problematic spell label %s found. Loot extrapolation for this set of loot would have run an increased risk of introducing bad data into the system.", log_source, private.previous_spell_id)
|
MMOSimca@344
|
1990 return false
|
MMOSimca@344
|
1991 end
|
MMOSimca@344
|
1992
|
jcallahan@322
|
1993 for loot_slot = 1, _G.GetNumLootItems() do
|
jcallahan@322
|
1994 local loot_info = {
|
jcallahan@322
|
1995 _G.GetLootSourceInfo(loot_slot)
|
jcallahan@322
|
1996 }
|
jcallahan@322
|
1997
|
jcallahan@322
|
1998 for loot_index = 1, #loot_info, 2 do
|
jcallahan@322
|
1999 local source_guid = loot_info[loot_index]
|
jcallahan@322
|
2000
|
jcallahan@322
|
2001 if not extrapolated_guid_registry[source_guid] then
|
jcallahan@322
|
2002 local unit_type, unit_idnum = ParseGUID(source_guid)
|
jcallahan@322
|
2003
|
jcallahan@322
|
2004 if unit_type and unit_idnum then
|
jcallahan@322
|
2005 extrapolated_guid_registry[source_guid] = {
|
jcallahan@322
|
2006 unit_type,
|
jcallahan@322
|
2007 unit_idnum
|
jcallahan@322
|
2008 }
|
jcallahan@322
|
2009
|
jcallahan@322
|
2010 num_guids = num_guids + 1
|
jcallahan@322
|
2011 end
|
jcallahan@322
|
2012 end
|
jcallahan@322
|
2013 end
|
jcallahan@322
|
2014 end
|
jcallahan@322
|
2015
|
jcallahan@322
|
2016 if num_guids == 0 then
|
jcallahan@322
|
2017 Debug("%s: No GUIDs found in loot. Blank loot window?", log_source)
|
jcallahan@322
|
2018 return false
|
jcallahan@322
|
2019 end
|
jcallahan@326
|
2020
|
jcallahan@322
|
2021 local num_npcs = 0
|
jcallahan@322
|
2022 local num_objects = 0
|
jcallahan@324
|
2023 local num_itemcontainers = 0
|
jcallahan@322
|
2024
|
jcallahan@322
|
2025 for source_guid, guid_data in pairs(extrapolated_guid_registry) do
|
jcallahan@322
|
2026 local unit_type = guid_data[1]
|
mmosimca@516
|
2027 local loot_label = (unit_type == private.UNIT_TYPES.OBJECT) and "opening" or (UnitTypeIsNPC(unit_type) and "drops") or ((unit_type == private.UNIT_TYPES.ITEM) and "contains")
|
jcallahan@322
|
2028
|
jcallahan@322
|
2029 if loot_label then
|
jcallahan@322
|
2030 local unit_idnum = guid_data[2]
|
jcallahan@322
|
2031
|
jcallahan@322
|
2032 if loot_guid_registry[loot_label] and loot_guid_registry[loot_label][source_guid] then
|
jcallahan@322
|
2033 Debug("%s: Previously scanned loot for unit with GUID %s and identifier %s.", log_source, source_guid, unit_idnum)
|
jcallahan@322
|
2034 elseif unit_type == private.UNIT_TYPES.OBJECT and unit_idnum ~= OBJECT_ID_FISHING_BOBBER then
|
jcallahan@322
|
2035 current_action.loot_label = loot_label
|
jcallahan@322
|
2036 current_action.spell_label = "OPENING"
|
jcallahan@322
|
2037 current_action.target_type = AF.OBJECT
|
jcallahan@322
|
2038 current_action.identifier = unit_idnum
|
jcallahan@322
|
2039 num_objects = num_objects + 1
|
jcallahan@322
|
2040 elseif UnitTypeIsNPC(unit_type) then
|
jcallahan@322
|
2041 current_action.loot_label = loot_label
|
jcallahan@322
|
2042 current_action.target_type = AF.NPC
|
jcallahan@322
|
2043 current_action.identifier = unit_idnum
|
jcallahan@322
|
2044 num_npcs = num_npcs + 1
|
mmosimca@516
|
2045 elseif unit_type == private.UNIT_TYPES.ITEM then
|
jcallahan@324
|
2046 current_action.loot_label = loot_label
|
jcallahan@324
|
2047 current_action.target_type = AF.ITEM
|
jcallahan@324
|
2048 -- current_action.identifier assigned during loot verification.
|
jcallahan@324
|
2049 num_itemcontainers = num_itemcontainers + 1
|
jcallahan@322
|
2050 end
|
jcallahan@322
|
2051 else
|
jcallahan@322
|
2052 -- Bail here; not only do we not know what this unit is, but we don't want to attribute loot to something that doesn't actually drop it.
|
jcallahan@322
|
2053 Debug("%s: Unit with GUID %s has unsupported type for looting.", log_source, source_guid)
|
jcallahan@322
|
2054 return false
|
jcallahan@322
|
2055 end
|
jcallahan@322
|
2056 end
|
jcallahan@322
|
2057
|
jcallahan@322
|
2058 if not current_action.target_type then
|
jcallahan@322
|
2059 Debug("%s: Failure to obtain target_type.", log_source)
|
jcallahan@322
|
2060 return false
|
jcallahan@322
|
2061 end
|
jcallahan@322
|
2062
|
jcallahan@322
|
2063 -- We can't figure out what dropped the loot. This shouldn't ever happen, but hey - Blizzard does some awesome stuff on occasion.
|
jcallahan@324
|
2064 if (num_npcs > 0 and num_objects + num_itemcontainers > 0) or (num_objects > 0 and num_npcs + num_itemcontainers > 0) or (num_itemcontainers > 0 and num_npcs + num_objects > 0) then
|
jcallahan@324
|
2065 Debug("%s: Mixed target types are not supported. NPCs - %d, Objects - %d, Item Containers - %d.", log_source, num_npcs, num_objects, num_itemcontainers)
|
jcallahan@322
|
2066 return false
|
jcallahan@322
|
2067 end
|
jcallahan@322
|
2068
|
jcallahan@322
|
2069 return true
|
jcallahan@322
|
2070 end
|
jcallahan@322
|
2071
|
jcallahan@322
|
2072
|
MMOSimca@343
|
2073 function WDP:LOOT_OPENED(event_name)
|
MMOSimca@398
|
2074 ClearChatLootData()
|
MMOSimca@387
|
2075
|
jcallahan@132
|
2076 if current_loot then
|
jcallahan@322
|
2077 current_loot = nil
|
jcallahan@322
|
2078 Debug("%s: Previous loot did not process in time for this event. Attempting to extrapolate current_action from loot data.", event_name)
|
jcallahan@322
|
2079
|
jcallahan@322
|
2080 if not ExtrapolatedCurrentActionFromLootData(event_name) then
|
jcallahan@322
|
2081 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
|
jcallahan@322
|
2082 return
|
jcallahan@322
|
2083 end
|
jcallahan@18
|
2084 end
|
jcallahan@151
|
2085
|
jcallahan@151
|
2086 if not current_action.target_type then
|
jcallahan@322
|
2087 if not ExtrapolatedCurrentActionFromLootData(event_name) then
|
jcallahan@322
|
2088 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
|
jcallahan@322
|
2089 return
|
jcallahan@322
|
2090 end
|
jcallahan@151
|
2091 end
|
MMOSimca@343
|
2092 local verify_func = LOOT_OPENED_VERIFY_FUNCS[current_action.target_type]
|
MMOSimca@343
|
2093 local update_func = LOOT_OPENED_UPDATE_FUNCS[current_action.target_type]
|
jcallahan@13
|
2094
|
jcallahan@14
|
2095 if not verify_func or not update_func then
|
jcallahan@322
|
2096 Debug("%s: The current action's target type is unsupported or nil.", event_name)
|
jcallahan@13
|
2097 return
|
jcallahan@13
|
2098 end
|
jcallahan@13
|
2099
|
mmosimca@522
|
2100 if type(verify_func) == "function" and not verify_func() then
|
jcallahan@324
|
2101 Debug("%s: The current action type, %s, is supported but has failed loot verification.", event_name, private.ACTION_TYPE_NAMES[current_action.target_type])
|
jcallahan@14
|
2102 return
|
jcallahan@14
|
2103 end
|
jcallahan@80
|
2104 local guids_used = {}
|
jcallahan@132
|
2105
|
jcallahan@301
|
2106 InitializeCurrentLoot()
|
jcallahan@217
|
2107 loot_guid_registry[current_loot.label] = loot_guid_registry[current_loot.label] or {}
|
jcallahan@217
|
2108
|
jcallahan@55
|
2109 for loot_slot = 1, _G.GetNumLootItems() do
|
MMOSimca@581
|
2110 local texture_filedata_id, item_text, slot_quantity, _, locked = _G.GetLootSlotInfo(loot_slot)
|
jcallahan@55
|
2111 local slot_type = _G.GetLootSlotType(loot_slot)
|
catherton@463
|
2112 local loot_info = { _G.GetLootSourceInfo(loot_slot) }
|
catherton@464
|
2113 local loot_link = _G.GetLootSlotLink(loot_slot)
|
jcallahan@13
|
2114
|
jcallahan@237
|
2115 -- Odd index is GUID, even is count.
|
jcallahan@237
|
2116 for loot_index = 1, #loot_info, 2 do
|
jcallahan@237
|
2117 local source_guid = loot_info[loot_index]
|
jcallahan@75
|
2118
|
jcallahan@237
|
2119 if not loot_guid_registry[current_loot.label][source_guid] then
|
jcallahan@237
|
2120 local loot_quantity = loot_info[loot_index + 1]
|
jcallahan@324
|
2121 -- There is a new bug in 5.4.0 that causes GetLootSlotInfo() to (rarely) return nil values for slot_quantity.
|
jcallahan@324
|
2122 if slot_quantity then
|
jcallahan@324
|
2123 -- We need slot_quantity to account for an old bug where loot_quantity is sometimes '1' for stacks of items, such as cloth.
|
jcallahan@324
|
2124 if slot_quantity > loot_quantity then
|
jcallahan@324
|
2125 loot_quantity = slot_quantity
|
jcallahan@324
|
2126 end
|
jcallahan@324
|
2127 local source_type, source_id = ParseGUID(source_guid)
|
MMOSimca@329
|
2128 local source_key = ("%s:%d"):format(source_type, source_id)
|
jcallahan@324
|
2129
|
MMOSimca@581
|
2130 if slot_type == ENUM_LOOTSLOTTYPE_ITEM then
|
catherton@464
|
2131 if loot_link then
|
catherton@464
|
2132 local item_id = ItemLinkToID(loot_link)
|
catherton@464
|
2133 Debug("GUID: %s - Type:ID: %s - ItemID: %d - Amount: %d (%d)", loot_info[loot_index], source_key, item_id, loot_info[loot_index + 1], slot_quantity)
|
catherton@464
|
2134 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
catherton@464
|
2135 current_loot.sources[source_guid][item_id] = (current_loot.sources[source_guid][item_id] or 0) + loot_quantity
|
catherton@464
|
2136 guids_used[source_guid] = true
|
catherton@463
|
2137 else
|
catherton@463
|
2138 Debug("%s: Loot link is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
|
catherton@463
|
2139 end
|
MMOSimca@581
|
2140 elseif slot_type == ENUM_LOOTSLOTTYPE_MONEY then
|
jcallahan@324
|
2141 Debug("GUID: %s - Type:ID: %s - Money - Amount: %d (%d)", loot_info[loot_index], source_key, loot_info[loot_index + 1], slot_quantity)
|
jcallahan@324
|
2142 if current_loot.target_type == AF.ZONE then
|
jcallahan@324
|
2143 table.insert(current_loot.list, ("money:%d"):format(loot_quantity))
|
jcallahan@324
|
2144 else
|
jcallahan@324
|
2145 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
MMOSimca@367
|
2146 current_loot.sources[source_guid]["money"] = (current_loot.sources[source_guid]["money"] or 0) + loot_quantity
|
jcallahan@324
|
2147 guids_used[source_guid] = true
|
jcallahan@324
|
2148 end
|
MMOSimca@581
|
2149 elseif slot_type == ENUM_LOOTSLOTTYPE_CURRENCY then
|
jcallahan@324
|
2150 -- Same bug with GetLootSlotInfo() will screw up currency when it happens, so we won't process this slot's loot.
|
catherton@463
|
2151 if loot_link then
|
mmosimca@496
|
2152 local currency_id = CurrencyLinkToID(loot_link)
|
mmosimca@496
|
2153 Debug("GUID: %s - Type:ID: %s - Currency: %d - Amount: %d (%d)", loot_info[loot_index], source_key, currency_id, loot_info[loot_index + 1], slot_quantity)
|
jcallahan@324
|
2154 if current_loot.target_type == AF.ZONE then
|
mmosimca@496
|
2155 table.insert(current_loot.list, ("currency:%d:%d"):format(loot_quantity, currency_id))
|
jcallahan@324
|
2156 else
|
mmosimca@496
|
2157 local currency_token = ("currency:%d"):format(currency_id)
|
jcallahan@324
|
2158
|
jcallahan@324
|
2159 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
MMOSimca@367
|
2160 current_loot.sources[source_guid][currency_token] = (current_loot.sources[source_guid][currency_token] or 0) + loot_quantity
|
jcallahan@324
|
2161 guids_used[source_guid] = true
|
jcallahan@324
|
2162 end
|
jcallahan@324
|
2163 else
|
catherton@463
|
2164 Debug("%s: Loot link is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
|
jcallahan@324
|
2165 end
|
MMOSimca@581
|
2166 else
|
MMOSimca@581
|
2167 Debug("Unknown LootSlotType %d. GUID: %s - Type:ID: %s - Loot Slot: %d - Loot Link: %s", slot_type, loot_info[loot_index], source_key, loot_slot, loot_link or "")
|
jcallahan@308
|
2168 end
|
jcallahan@324
|
2169 else
|
jcallahan@324
|
2170 -- If this is nil, then the item's quantity could be wrong if loot_quantity is wrong, so we won't process this slot's loot.
|
catherton@463
|
2171 Debug("%s: Slot quantity is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
|
jcallahan@79
|
2172 end
|
jcallahan@75
|
2173 end
|
jcallahan@13
|
2174 end
|
jcallahan@13
|
2175 end
|
jcallahan@80
|
2176
|
jcallahan@81
|
2177 for guid in pairs(guids_used) do
|
jcallahan@217
|
2178 loot_guid_registry[current_loot.label][guid] = true
|
jcallahan@80
|
2179 end
|
jcallahan@13
|
2180 update_func()
|
jcallahan@1
|
2181 end
|
jcallahan@13
|
2182 end -- do-block
|
jcallahan@0
|
2183
|
jcallahan@0
|
2184
|
jcallahan@89
|
2185 function WDP:MAIL_SHOW(event_name)
|
MMOSimca@436
|
2186 WDP:StopChatLootRecording(event_name)
|
jcallahan@89
|
2187 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@89
|
2188
|
jcallahan@89
|
2189 if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT then
|
jcallahan@89
|
2190 return
|
jcallahan@89
|
2191 end
|
jcallahan@89
|
2192 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@89
|
2193 end
|
jcallahan@89
|
2194
|
jcallahan@89
|
2195
|
jcallahan@44
|
2196 do
|
jcallahan@44
|
2197 local POINT_MATCH_PATTERNS = {
|
jcallahan@44
|
2198 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2199 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2200 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_5V5:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2201 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_BG:gsub("%%d", "(%%d+)")),
|
jcallahan@44
|
2202 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3_BG:gsub("%%d", "(%%d+)")),
|
jcallahan@44
|
2203 }
|
jcallahan@5
|
2204
|
jcallahan@68
|
2205 local ITEM_REQ_REPUTATION_MATCH = "Requires (.-) %- (.*)"
|
jcallahan@87
|
2206 local ITEM_REQ_QUEST_MATCH1 = "Requires: .*"
|
jcallahan@87
|
2207 local ITEM_REQ_QUEST_MATCH2 = "Must have completed: .*"
|
jcallahan@68
|
2208
|
jcallahan@133
|
2209 local current_merchant
|
jcallahan@133
|
2210 local merchant_standing
|
jcallahan@133
|
2211
|
jcallahan@133
|
2212 function WDP:MERCHANT_CLOSED(event_name)
|
MMOSimca@436
|
2213 WDP:ResumeChatLootRecording(event_name)
|
jcallahan@133
|
2214 current_merchant = nil
|
jcallahan@133
|
2215 merchant_standing = nil
|
jcallahan@133
|
2216 end
|
jcallahan@133
|
2217
|
jcallahan@133
|
2218
|
jcallahan@89
|
2219 function WDP:UpdateMerchantItems(event_name)
|
jcallahan@144
|
2220 if not current_merchant or event_name == "MERCHANT_SHOW" then
|
MMOSimca@436
|
2221 WDP:StopChatLootRecording(event_name)
|
jcallahan@195
|
2222 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@4
|
2223
|
jcallahan@171
|
2224 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@133
|
2225 return
|
jcallahan@133
|
2226 end
|
MMOSimca@584
|
2227
|
MMOSimca@584
|
2228 -- Can't do this in instances now, at least not by tooltip unit scanning
|
MMOSimca@584
|
2229 if not III() then
|
MMOSimca@584
|
2230 local _, faction_standing = UnitFactionStanding("npc")
|
MMOSimca@584
|
2231 merchant_standing = faction_standing
|
MMOSimca@584
|
2232 end
|
MMOSimca@584
|
2233
|
jcallahan@133
|
2234 current_merchant = NPCEntry(unit_idnum)
|
jcallahan@133
|
2235 current_merchant.sells = current_merchant.sells or {}
|
jcallahan@44
|
2236 end
|
jcallahan@55
|
2237 local current_filters = _G.GetMerchantFilter()
|
jcallahan@57
|
2238 _G.SetMerchantFilter(_G.LE_LOOT_FILTER_ALL)
|
jcallahan@57
|
2239 _G.MerchantFrame_Update()
|
jcallahan@57
|
2240
|
jcallahan@150
|
2241 local num_items = _G.GetMerchantNumItems()
|
jcallahan@150
|
2242
|
jcallahan@44
|
2243 for item_index = 1, num_items do
|
MMOSimca@584
|
2244 local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.C_MerchantFrame.GetItemInfo(item_index)
|
MMOSimca@584
|
2245 local itemInfoTable = _G.C_MerchantFrame.GetItemInfo(item_index)
|
jcallahan@44
|
2246 local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index))
|
jcallahan@5
|
2247
|
jcallahan@324
|
2248 DatamineTT:ClearLines()
|
jcallahan@324
|
2249 DatamineTT:SetMerchantItem(item_index)
|
jcallahan@324
|
2250
|
jcallahan@324
|
2251 if not item_id then
|
jcallahan@324
|
2252 local item_name, item_link = DatamineTT:GetItem()
|
jcallahan@324
|
2253 item_id = ItemLinkToID(item_link)
|
MMOSimca@354
|
2254 -- GetMerchantItemLink() still ocassionally fails as of Patch 6.0.2. It fails so badly that debug functions cause considerable slowdown.
|
jcallahan@324
|
2255 end
|
jcallahan@324
|
2256
|
jcallahan@44
|
2257 if item_id and item_id > 0 then
|
MMOSimca@584
|
2258 local price_string = ActualCopperCost(itemInfoTable.price, merchant_standing)
|
jcallahan@5
|
2259
|
jcallahan@68
|
2260 local num_lines = DatamineTT:NumLines()
|
jcallahan@68
|
2261
|
jcallahan@68
|
2262 for line_index = 1, num_lines do
|
jcallahan@68
|
2263 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@68
|
2264
|
jcallahan@68
|
2265 if not current_line then
|
jcallahan@68
|
2266 break
|
jcallahan@68
|
2267 end
|
jcallahan@68
|
2268 local faction, reputation = current_line:GetText():match(ITEM_REQ_REPUTATION_MATCH)
|
jcallahan@68
|
2269
|
jcallahan@68
|
2270 if faction or reputation then
|
jcallahan@68
|
2271 DBEntry("items", item_id).req_reputation = ("%s:%s"):format(faction:gsub("-", ""), reputation:upper())
|
jcallahan@68
|
2272 break
|
jcallahan@68
|
2273 end
|
jcallahan@68
|
2274 end
|
jcallahan@68
|
2275
|
jcallahan@87
|
2276 for line_index = 1, num_lines do
|
jcallahan@87
|
2277 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@87
|
2278
|
jcallahan@87
|
2279 if not current_line then
|
jcallahan@87
|
2280 break
|
jcallahan@87
|
2281 end
|
jcallahan@87
|
2282 local line_text = current_line:GetText()
|
jcallahan@87
|
2283 local quest_name = line_text:match(ITEM_REQ_QUEST_MATCH1) or line_text:match(ITEM_REQ_QUEST_MATCH2)
|
jcallahan@87
|
2284
|
jcallahan@87
|
2285 if quest_name then
|
jcallahan@87
|
2286 DBEntry("items", item_id).req_quest = ("%s"):format(quest_name:gsub("(.+): ", ""), quest_name)
|
jcallahan@87
|
2287 break
|
jcallahan@87
|
2288 end
|
jcallahan@87
|
2289 end
|
jcallahan@87
|
2290
|
MMOSimca@584
|
2291 if itemInfoTable.hasExtendedCost then
|
jcallahan@53
|
2292 local battleground_rating = 0
|
jcallahan@53
|
2293 local personal_rating = 0
|
jcallahan@53
|
2294 local required_season_amount
|
jcallahan@5
|
2295
|
jcallahan@68
|
2296 for line_index = 1, num_lines do
|
jcallahan@44
|
2297 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@5
|
2298
|
jcallahan@44
|
2299 if not current_line then
|
jcallahan@44
|
2300 break
|
jcallahan@44
|
2301 end
|
jcallahan@53
|
2302 required_season_amount = current_line:GetText():match("Requires earning a total of (%d+)\n(.-) for the season.")
|
jcallahan@5
|
2303
|
jcallahan@44
|
2304 for match_index = 1, #POINT_MATCH_PATTERNS do
|
jcallahan@44
|
2305 local match1, match2 = current_line:GetText():match(POINT_MATCH_PATTERNS[match_index])
|
jcallahan@53
|
2306 personal_rating = personal_rating + (match1 or 0)
|
jcallahan@53
|
2307 battleground_rating = battleground_rating + (match2 or 0)
|
jcallahan@5
|
2308
|
jcallahan@44
|
2309 if match1 or match2 then
|
jcallahan@44
|
2310 break
|
jcallahan@44
|
2311 end
|
jcallahan@44
|
2312 end
|
jcallahan@5
|
2313 end
|
jcallahan@44
|
2314 local currency_list = {}
|
jcallahan@44
|
2315 local item_count = _G.GetMerchantItemCostInfo(item_index)
|
jcallahan@50
|
2316
|
mmosimca@518
|
2317 -- Keeping this around in case Blizzard makes the two ratings (personal and battleground) diverge at some point
|
mmosimca@518
|
2318 --price_string = ("%s:%s:%s:%s"):format(price_string, battleground_rating, personal_rating, required_season_amount or 0)
|
jcallahan@53
|
2319 price_string = ("%s:%s:%s"):format(price_string, personal_rating, required_season_amount or 0)
|
jcallahan@5
|
2320
|
jcallahan@44
|
2321 for cost_index = 1, item_count do
|
jcallahan@324
|
2322 -- The third return (Blizz calls "currency_link") of GetMerchantItemCostItem only returns item links as of Patch 5.3.0.
|
MMOSimca@540
|
2323 local texture_id, amount_required, hyperlink, name = _G.GetMerchantItemCostItem(item_index, cost_index)
|
mmosimca@496
|
2324
|
MMOSimca@581
|
2325 if hyperlink then
|
MMOSimca@581
|
2326 -- Try to get item ID
|
MMOSimca@581
|
2327 local item_id = ItemLinkToID(hyperlink)
|
MMOSimca@581
|
2328
|
MMOSimca@581
|
2329 -- FUTURE: At some point, we should make the output from these two cases (item_id vs currency_id) slightly different, so that WoWDB doesn't have to guess if it is a currency or item
|
MMOSimca@581
|
2330 -- Handle cases when the additional cost is another item
|
MMOSimca@581
|
2331 if item_id and item_id > 0 then
|
MMOSimca@581
|
2332 currency_list[#currency_list + 1] = ("(%s:%d)"):format(amount_required, item_id)
|
MMOSimca@581
|
2333 else
|
MMOSimca@581
|
2334 -- Try to get currency ID
|
MMOSimca@581
|
2335 local currency_id = CurrencyLinkToID(hyperlink)
|
MMOSimca@581
|
2336 if currency_id and currency_id > 0 then
|
MMOSimca@581
|
2337 currency_list[#currency_list + 1] = ("(%s:%d)"):format(amount_required, currency_id)
|
MMOSimca@581
|
2338 else
|
MMOSimca@581
|
2339 Debug("UpdateMerchantItems: Failed to get item ID and failed to get currency ID for item index %d and cost index %d with hyperlink %s", item_index, cost_index, hyperlink)
|
MMOSimca@581
|
2340 end
|
MMOSimca@581
|
2341 end
|
MMOSimca@581
|
2342 end
|
jcallahan@44
|
2343 end
|
jcallahan@44
|
2344
|
jcallahan@44
|
2345 for currency_index = 1, #currency_list do
|
jcallahan@44
|
2346 price_string = ("%s:%s"):format(price_string, currency_list[currency_index])
|
jcallahan@5
|
2347 end
|
jcallahan@5
|
2348 end
|
MMOSimca@584
|
2349 current_merchant.sells[item_id] = ("%s:%s:[%s]"):format(itemInfoTable.numAvailable, itemInfoTable.stackCount, price_string)
|
jcallahan@44
|
2350 end
|
jcallahan@44
|
2351 end
|
jcallahan@5
|
2352
|
jcallahan@44
|
2353 if _G.CanMerchantRepair() then
|
jcallahan@133
|
2354 current_merchant.can_repair = true
|
jcallahan@5
|
2355 end
|
jcallahan@57
|
2356 _G.SetMerchantFilter(current_filters)
|
jcallahan@57
|
2357 _G.MerchantFrame_Update()
|
jcallahan@4
|
2358 end
|
jcallahan@44
|
2359 end -- do-block
|
jcallahan@4
|
2360
|
jcallahan@89
|
2361
|
jcallahan@92
|
2362 function WDP:PET_BAR_UPDATE(event_name)
|
MMOSimca@336
|
2363 if not private.NON_LOOT_SPELL_LABELS[current_action.spell_label] then
|
jcallahan@25
|
2364 return
|
jcallahan@25
|
2365 end
|
jcallahan@34
|
2366 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("pet"))
|
jcallahan@25
|
2367
|
jcallahan@171
|
2368 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@25
|
2369 return
|
jcallahan@25
|
2370 end
|
jcallahan@29
|
2371 NPCEntry(unit_idnum).mind_control = true
|
jcallahan@122
|
2372 table.wipe(current_action)
|
jcallahan@25
|
2373 end
|
jcallahan@25
|
2374
|
jcallahan@25
|
2375
|
MMOSimca@368
|
2376 -- This function produces data currently unused by wowdb.com, and it causes unneeded bloat in the raw lua DB.
|
MMOSimca@442
|
2377 --[[local LPJ = LibStub("LibPetJournal-2.0")
|
MMOSimca@442
|
2378 function WDP:PET_JOURNAL_LIST_UPDATE(event_name)
|
MMOSimca@346
|
2379 if DEBUGGING then
|
jcallahan@309
|
2380 return
|
jcallahan@309
|
2381 end
|
jcallahan@309
|
2382
|
jcallahan@115
|
2383 local num_pets = LPJ:NumPets()
|
jcallahan@115
|
2384
|
jcallahan@115
|
2385 for index, pet_id in LPJ:IteratePetIDs() do
|
jcallahan@115
|
2386 local _, _, is_owned, _, level, _, _, name, icon, pet_type, npc_id, _, _, is_wild = _G.C_PetJournal.GetPetInfoByIndex(index)
|
jcallahan@115
|
2387
|
jcallahan@115
|
2388 if is_owned then
|
jcallahan@115
|
2389 local health, max_health, attack, speed, rarity = _G.C_PetJournal.GetPetStats(pet_id)
|
jcallahan@115
|
2390
|
jcallahan@139
|
2391 if rarity then
|
jcallahan@139
|
2392 local rarity_name = _G["BATTLE_PET_BREED_QUALITY" .. rarity]
|
jcallahan@139
|
2393 local npc = NPCEntry(npc_id)
|
jcallahan@139
|
2394 npc.wild_pet = is_wild or nil
|
jcallahan@139
|
2395 npc.battle_pet_data = npc.battle_pet_data or {}
|
jcallahan@139
|
2396 npc.battle_pet_data[rarity_name] = npc.battle_pet_data[rarity_name] or {}
|
jcallahan@139
|
2397 npc.battle_pet_data[rarity_name]["level_" .. level] = npc.battle_pet_data[rarity_name]["level_" .. level] or {}
|
jcallahan@139
|
2398
|
jcallahan@139
|
2399 local data = npc.battle_pet_data[rarity_name]["level_" .. level]
|
jcallahan@139
|
2400 data.max_health = max_health
|
jcallahan@139
|
2401 data.attack = attack
|
jcallahan@139
|
2402 data.speed = speed
|
jcallahan@139
|
2403 end
|
jcallahan@115
|
2404 end
|
jcallahan@115
|
2405 end
|
MMOSimca@368
|
2406 end]]--
|
jcallahan@115
|
2407
|
jcallahan@115
|
2408
|
jcallahan@156
|
2409 function WDP:PLAYER_REGEN_DISABLED(event_name)
|
jcallahan@156
|
2410 private.in_combat = true
|
jcallahan@156
|
2411 end
|
jcallahan@156
|
2412
|
jcallahan@156
|
2413
|
jcallahan@156
|
2414 function WDP:PLAYER_REGEN_ENABLED(event_name)
|
jcallahan@156
|
2415 private.in_combat = nil
|
jcallahan@156
|
2416 end
|
jcallahan@156
|
2417
|
jcallahan@156
|
2418
|
jcallahan@118
|
2419 function WDP:PLAYER_TARGET_CHANGED(event_name)
|
jcallahan@215
|
2420 if not TargetedNPC() then
|
jcallahan@118
|
2421 return
|
jcallahan@2
|
2422 end
|
jcallahan@151
|
2423 current_action.target_type = AF.NPC
|
jcallahan@118
|
2424 self:UpdateTargetLocation()
|
jcallahan@118
|
2425 end
|
jcallahan@2
|
2426
|
jcallahan@89
|
2427
|
jcallahan@12
|
2428 do
|
jcallahan@12
|
2429 local function UpdateQuestJuncture(point)
|
jcallahan@12
|
2430 local unit_name = _G.UnitName("questnpc")
|
jcallahan@9
|
2431
|
jcallahan@12
|
2432 if not unit_name then
|
jcallahan@12
|
2433 return
|
jcallahan@12
|
2434 end
|
jcallahan@34
|
2435 local unit_type, unit_id = ParseGUID(_G.UnitGUID("questnpc"))
|
MMOSimca@351
|
2436 Debug("UpdateQuestJuncture: Updating quest juncture for %s.", ("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id))
|
jcallahan@12
|
2437 if unit_type == private.UNIT_TYPES.OBJECT then
|
jcallahan@38
|
2438 UpdateDBEntryLocation("objects", unit_id)
|
jcallahan@12
|
2439 end
|
jcallahan@19
|
2440 local quest = DBEntry("quests", _G.GetQuestID())
|
jcallahan@12
|
2441 quest[point] = quest[point] or {}
|
MMOSimca@329
|
2442 quest[point][("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id)] = true
|
jcallahan@24
|
2443
|
jcallahan@24
|
2444 return quest
|
jcallahan@12
|
2445 end
|
jcallahan@10
|
2446
|
jcallahan@12
|
2447
|
jcallahan@92
|
2448 function WDP:QUEST_COMPLETE(event_name)
|
jcallahan@97
|
2449 local quest = UpdateQuestJuncture("end")
|
catherton@465
|
2450
|
MMOSimca@446
|
2451 if not quest then
|
MMOSimca@446
|
2452 return
|
MMOSimca@446
|
2453 end
|
jcallahan@97
|
2454
|
jcallahan@112
|
2455 if ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@112
|
2456 quest.reward_text = ReplaceKeywords(_G.GetRewardText())
|
jcallahan@112
|
2457 end
|
jcallahan@67
|
2458 -- Make sure the quest NPC isn't erroneously recorded as giving reputation for quests which award it.
|
jcallahan@177
|
2459 ClearKilledNPC()
|
jcallahan@10
|
2460 end
|
jcallahan@10
|
2461
|
jcallahan@12
|
2462
|
jcallahan@92
|
2463 function WDP:QUEST_DETAIL(event_name)
|
jcallahan@24
|
2464 local quest = UpdateQuestJuncture("begin")
|
jcallahan@24
|
2465
|
jcallahan@46
|
2466 if not quest then
|
jcallahan@46
|
2467 return
|
jcallahan@46
|
2468 end
|
jcallahan@24
|
2469 quest.classes = quest.classes or {}
|
jcallahan@27
|
2470 quest.classes[PLAYER_CLASS] = true
|
jcallahan@24
|
2471
|
jcallahan@24
|
2472 quest.races = quest.races or {}
|
jcallahan@100
|
2473 quest.races[(PLAYER_RACE == "Pandaren") and ("%s_%s"):format(PLAYER_RACE, PLAYER_FACTION or "Neutral") or PLAYER_RACE] = true
|
jcallahan@10
|
2474 end
|
jcallahan@12
|
2475 end -- do-block
|
jcallahan@9
|
2476
|
jcallahan@9
|
2477
|
jcallahan@92
|
2478 function WDP:QUEST_LOG_UPDATE(event_name)
|
MMOSimca@581
|
2479 local selected_quest = _G.C_QuestLog.GetSelectedQuest() -- Save current selection to be restored when we're done.
|
jcallahan@36
|
2480 local entry_index, processed_quests = 1, 0
|
MMOSimca@581
|
2481 local _, num_quests = _G.C_QuestLog.GetNumQuestLogEntries()
|
jcallahan@36
|
2482
|
jcallahan@36
|
2483 while processed_quests <= num_quests do
|
MMOSimca@581
|
2484 local info = _G.C_QuestLog.GetInfo(entry_index)
|
MMOSimca@581
|
2485
|
MMOSimca@581
|
2486 if info.questID == 0 then
|
jcallahan@84
|
2487 processed_quests = processed_quests + 1
|
MMOSimca@581
|
2488 elseif not info.isHeader then
|
MMOSimca@581
|
2489 _G.C_QuestLog.SetSelectedQuest(entry_index);
|
MMOSimca@581
|
2490
|
MMOSimca@581
|
2491 local quest = DBEntry("quests", info.questID)
|
jcallahan@36
|
2492 quest.timer = _G.GetQuestLogTimeLeft()
|
MMOSimca@581
|
2493 quest.can_share = _G.C_QuestLog.IsPushableQuest(info.questID) and true or nil
|
jcallahan@36
|
2494 processed_quests = processed_quests + 1
|
jcallahan@36
|
2495 end
|
jcallahan@36
|
2496 entry_index = entry_index + 1
|
jcallahan@36
|
2497 end
|
MMOSimca@581
|
2498 _G.C_QuestLog.SetSelectedQuest(selected_quest)
|
jcallahan@4
|
2499 self:UnregisterEvent("QUEST_LOG_UPDATE")
|
jcallahan@4
|
2500 end
|
jcallahan@4
|
2501
|
jcallahan@4
|
2502
|
jcallahan@97
|
2503 function WDP:QUEST_PROGRESS(event_name)
|
jcallahan@112
|
2504 if not ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@112
|
2505 return
|
jcallahan@112
|
2506 end
|
jcallahan@97
|
2507 DBEntry("quests", _G.GetQuestID()).progress_text = ReplaceKeywords(_G.GetProgressText())
|
jcallahan@97
|
2508 end
|
jcallahan@97
|
2509
|
jcallahan@97
|
2510
|
jcallahan@92
|
2511 function WDP:UNIT_QUEST_LOG_CHANGED(event_name, unit_id)
|
jcallahan@4
|
2512 if unit_id ~= "player" then
|
jcallahan@4
|
2513 return
|
jcallahan@4
|
2514 end
|
jcallahan@4
|
2515 self:RegisterEvent("QUEST_LOG_UPDATE")
|
jcallahan@4
|
2516 end
|
jcallahan@4
|
2517
|
jcallahan@4
|
2518
|
MMOSimca@581
|
2519 -- This functionality is broken and should be rethought entirely in the wake of 10.0
|
MMOSimca@581
|
2520 --[[
|
jcallahan@92
|
2521 do
|
jcallahan@92
|
2522 local TRADESKILL_TOOLS = {
|
jcallahan@92
|
2523 Anvil = anvil_spell_ids,
|
jcallahan@92
|
2524 Forge = forge_spell_ids,
|
jcallahan@92
|
2525 }
|
jcallahan@92
|
2526
|
jcallahan@92
|
2527
|
jcallahan@167
|
2528 local function RegisterTools(tradeskill_name, tradeskill_index)
|
catherton@479
|
2529 local link = _G.C_TradeSkillUI.GetRecipeLink(tradeskill_index)
|
catherton@465
|
2530
|
MMOSimca@352
|
2531 if link then
|
MMOSimca@352
|
2532 local spell_id = tonumber(link:match("^|c%x%x%x%x%x%x%x%x|H%w+:(%d+)"))
|
catherton@479
|
2533 local required_tool = _G.C_TradeSkillUI.GetRecipeTools(tradeskill_index)
|
MMOSimca@352
|
2534
|
MMOSimca@352
|
2535 if required_tool then
|
MMOSimca@352
|
2536 for tool_name, registry in pairs(TRADESKILL_TOOLS) do
|
MMOSimca@352
|
2537 if required_tool:find(tool_name) then
|
MMOSimca@352
|
2538 registry[spell_id] = true
|
MMOSimca@352
|
2539 end
|
jcallahan@167
|
2540 end
|
jcallahan@167
|
2541 end
|
jcallahan@167
|
2542 end
|
jcallahan@167
|
2543 end
|
jcallahan@167
|
2544
|
jcallahan@167
|
2545
|
jcallahan@92
|
2546 function WDP:TRADE_SKILL_SHOW(event_name)
|
catherton@479
|
2547 local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
|
jcallahan@92
|
2548
|
jcallahan@92
|
2549 if profession_name == _G.UNKNOWN then
|
jcallahan@92
|
2550 return
|
jcallahan@92
|
2551 end
|
jcallahan@167
|
2552 TradeSkillExecutePer(RegisterTools)
|
jcallahan@92
|
2553 end
|
jcallahan@92
|
2554 end -- do-block
|
jcallahan@92
|
2555
|
jcallahan@92
|
2556
|
jcallahan@167
|
2557 function WDP:TRAINER_CLOSED(event_name)
|
jcallahan@167
|
2558 private.trainer_shown = nil
|
jcallahan@167
|
2559 end
|
jcallahan@167
|
2560
|
jcallahan@167
|
2561
|
jcallahan@92
|
2562 function WDP:TRAINER_SHOW(event_name)
|
jcallahan@232
|
2563 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@164
|
2564 local trainer = NPCEntry(unit_idnum)
|
jcallahan@58
|
2565
|
jcallahan@164
|
2566 if not trainer then
|
jcallahan@58
|
2567 return
|
jcallahan@58
|
2568 end
|
jcallahan@331
|
2569 local _, trainer_standing = UnitFactionStanding("npc")
|
jcallahan@164
|
2570 trainer.teaches = trainer.teaches or {}
|
jcallahan@27
|
2571
|
jcallahan@167
|
2572 private.trainer_shown = true
|
jcallahan@167
|
2573
|
jcallahan@27
|
2574 -- Get the initial trainer filters
|
MMOSimca@344
|
2575 local available = _G.GetTrainerServiceTypeFilter("available") and 1 or 0
|
MMOSimca@344
|
2576 local unavailable = _G.GetTrainerServiceTypeFilter("unavailable") and 1 or 0
|
MMOSimca@344
|
2577 local used = _G.GetTrainerServiceTypeFilter("used") and 1 or 0
|
jcallahan@27
|
2578
|
jcallahan@27
|
2579 -- Clear the trainer filters
|
MMOSimca@344
|
2580 _G.SetTrainerServiceTypeFilter("available", 1)
|
MMOSimca@344
|
2581 _G.SetTrainerServiceTypeFilter("unavailable", 1)
|
MMOSimca@344
|
2582 _G.SetTrainerServiceTypeFilter("used", 1)
|
jcallahan@27
|
2583
|
jcallahan@27
|
2584 for index = 1, _G.GetNumTrainerServices(), 1 do
|
jcallahan@27
|
2585 local spell_name, rank_name, _, _, required_level = _G.GetTrainerServiceInfo(index)
|
jcallahan@27
|
2586
|
jcallahan@27
|
2587 if spell_name then
|
jcallahan@27
|
2588 DatamineTT:ClearLines()
|
jcallahan@27
|
2589 DatamineTT:SetTrainerService(index)
|
jcallahan@27
|
2590
|
atcaleb@570
|
2591 local _, spell_id = DatamineTT:GetSpell()
|
jcallahan@27
|
2592
|
jcallahan@43
|
2593 if spell_id then
|
jcallahan@164
|
2594 local class_professions = trainer.teaches[PLAYER_CLASS]
|
jcallahan@164
|
2595
|
jcallahan@164
|
2596 if not class_professions then
|
jcallahan@164
|
2597 trainer.teaches[PLAYER_CLASS] = {}
|
jcallahan@164
|
2598 class_professions = trainer.teaches[PLAYER_CLASS]
|
jcallahan@164
|
2599 end
|
jcallahan@43
|
2600 local profession, min_skill = _G.GetTrainerServiceSkillReq(index)
|
jcallahan@43
|
2601 profession = profession or "General"
|
jcallahan@43
|
2602
|
jcallahan@164
|
2603 local profession_skills = class_professions[profession]
|
jcallahan@43
|
2604
|
jcallahan@43
|
2605 if not profession_skills then
|
jcallahan@43
|
2606 class_professions[profession] = {}
|
jcallahan@43
|
2607 profession_skills = class_professions[profession]
|
jcallahan@43
|
2608 end
|
jcallahan@173
|
2609 profession_skills[spell_id] = ("%d:%d:%d"):format(required_level, min_skill, _G.GetTrainerServiceCost(index))
|
jcallahan@27
|
2610 end
|
jcallahan@27
|
2611 end
|
jcallahan@27
|
2612 end
|
jcallahan@27
|
2613 -- Reset the filters to what they were before
|
MMOSimca@344
|
2614 _G.SetTrainerServiceTypeFilter("available", available or 0)
|
MMOSimca@344
|
2615 _G.SetTrainerServiceTypeFilter("unavailable", unavailable or 0)
|
MMOSimca@344
|
2616 _G.SetTrainerServiceTypeFilter("used", used or 0)
|
jcallahan@27
|
2617 end
|
MMOSimca@581
|
2618 ]]--
|
jcallahan@27
|
2619
|
jcallahan@27
|
2620
|
jcallahan@1
|
2621 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)
|
jcallahan@1
|
2622 if private.tracked_line or unit_id ~= "player" then
|
jcallahan@1
|
2623 return
|
jcallahan@1
|
2624 end
|
jcallahan@1
|
2625 local spell_label = private.SPELL_LABELS_BY_NAME[spell_name]
|
jcallahan@1
|
2626
|
jcallahan@1
|
2627 if not spell_label then
|
jcallahan@1
|
2628 return
|
jcallahan@1
|
2629 end
|
jcallahan@306
|
2630
|
MMOSimca@343
|
2631 Debug("UNIT_SPELLCAST_SENT: %s was cast.", spell_name)
|
jcallahan@150
|
2632 local item_name, item_link = _G.GameTooltip:GetItem()
|
jcallahan@150
|
2633 local unit_name, unit_id = _G.GameTooltip:GetUnit()
|
jcallahan@1
|
2634
|
jcallahan@150
|
2635 if not unit_name and _G.UnitName("target") == target_name then
|
jcallahan@150
|
2636 unit_name = target_name
|
jcallahan@150
|
2637 unit_id = "target"
|
jcallahan@1
|
2638 end
|
jcallahan@1
|
2639 local spell_flags = private.SPELL_FLAGS_BY_LABEL[spell_label]
|
jcallahan@28
|
2640 local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
|
MMOSimca@328
|
2641 if not (zone_name and area_id and x and y and map_level) then
|
mmosimca@508
|
2642 if not (_G.IsInInstance()) then
|
mmosimca@508
|
2643 Debug("%s: Missing current location data - %s, %s, %s, %s, %s.", event_name, tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
|
mmosimca@508
|
2644 end
|
MMOSimca@328
|
2645 return
|
MMOSimca@328
|
2646 end
|
jcallahan@28
|
2647
|
jcallahan@205
|
2648 table.wipe(current_action)
|
jcallahan@122
|
2649 current_action.instance_token = instance_token
|
jcallahan@122
|
2650 current_action.map_level = map_level
|
jcallahan@122
|
2651 current_action.x = x
|
jcallahan@122
|
2652 current_action.y = y
|
jcallahan@122
|
2653 current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
|
jcallahan@122
|
2654 current_action.spell_label = spell_label
|
jcallahan@105
|
2655
|
jcallahan@105
|
2656 if not private.NON_LOOT_SPELL_LABELS[spell_label] then
|
jcallahan@122
|
2657 current_action.loot_label = spell_label:lower()
|
jcallahan@105
|
2658 end
|
jcallahan@1
|
2659
|
jcallahan@151
|
2660 if unit_name and unit_name == target_name and not item_name then
|
jcallahan@16
|
2661 if bit.band(spell_flags, AF.NPC) == AF.NPC then
|
jcallahan@150
|
2662 if not unit_id or unit_name ~= target_name then
|
jcallahan@16
|
2663 return
|
jcallahan@16
|
2664 end
|
jcallahan@123
|
2665 current_action.target_type = AF.NPC
|
jcallahan@16
|
2666 end
|
jcallahan@16
|
2667 elseif bit.band(spell_flags, AF.ITEM) == AF.ITEM then
|
jcallahan@123
|
2668 current_action.target_type = AF.ITEM
|
jcallahan@16
|
2669
|
jcallahan@150
|
2670 if item_name and item_name == target_name then
|
jcallahan@150
|
2671 current_action.identifier = ItemLinkToID(item_link)
|
jcallahan@16
|
2672 elseif target_name and target_name ~= "" then
|
jcallahan@331
|
2673 local _, item_link = _G.GetItemInfo(target_name)
|
jcallahan@331
|
2674 current_action.identifier = ItemLinkToID(item_link)
|
jcallahan@16
|
2675 end
|
jcallahan@150
|
2676 elseif not item_name and not unit_name then
|
jcallahan@1
|
2677 if bit.band(spell_flags, AF.OBJECT) == AF.OBJECT then
|
jcallahan@17
|
2678 if target_name == "" then
|
jcallahan@17
|
2679 return
|
jcallahan@17
|
2680 end
|
jcallahan@122
|
2681 current_action.object_name = target_name
|
jcallahan@123
|
2682 current_action.target_type = AF.OBJECT
|
jcallahan@1
|
2683 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then
|
jcallahan@123
|
2684 current_action.target_type = AF.ZONE
|
jcallahan@1
|
2685 end
|
jcallahan@1
|
2686 end
|
jcallahan@1
|
2687 private.tracked_line = spell_line
|
jcallahan@0
|
2688 end
|
jcallahan@0
|
2689
|
jcallahan@94
|
2690
|
MMOSimca@393
|
2691 -- Triggered by bonus roll prompts, disenchant prompts, and in a few other rare circumstances
|
jcallahan@312
|
2692 function WDP:SPELL_CONFIRMATION_PROMPT(event_name, spell_id, confirm_type, text, duration, currency_id_cost)
|
jcallahan@306
|
2693 if private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id] then
|
jcallahan@306
|
2694 ClearKilledBossID()
|
jcallahan@306
|
2695 ClearLootToastContainerID()
|
MMOSimca@387
|
2696 raid_boss_id = private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id]
|
jcallahan@306
|
2697 else
|
MMOSimca@336
|
2698 Debug("%s: Spell ID %d is not a known raid boss 'Bonus' spell.", event_name, spell_id)
|
jcallahan@306
|
2699 return
|
jcallahan@1
|
2700 end
|
jcallahan@306
|
2701
|
jcallahan@324
|
2702 -- Assign existing loot data to boss if it exists
|
jcallahan@307
|
2703 if loot_toast_data then
|
MMOSimca@427
|
2704 local npc = NPCEntry(raid_boss_id)
|
MMOSimca@427
|
2705 if npc then
|
MMOSimca@427
|
2706 -- Create needed npc fields if required
|
MMOSimca@427
|
2707 local loot_label = "drops"
|
MMOSimca@427
|
2708 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
|
MMOSimca@427
|
2709 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
MMOSimca@427
|
2710 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@427
|
2711
|
MMOSimca@427
|
2712 for index = 1, #loot_toast_data do
|
MMOSimca@427
|
2713 local data = loot_toast_data[index]
|
MMOSimca@427
|
2714 local loot_type = data[1]
|
MMOSimca@427
|
2715 local hyperlink = data[2]
|
MMOSimca@427
|
2716 local quantity = data[3]
|
MMOSimca@427
|
2717
|
MMOSimca@427
|
2718 if loot_type == "item" then
|
MMOSimca@427
|
2719 local item_id = ItemLinkToID(hyperlink)
|
MMOSimca@427
|
2720 Debug("%s: Assigned stored item loot data - %s - %d:%d", event_name, hyperlink, item_id, quantity)
|
MMOSimca@427
|
2721 table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@427
|
2722 elseif loot_type == "money" then
|
MMOSimca@427
|
2723 Debug("%s: Assigned stored money loot data - money:%d", event_name, quantity)
|
MMOSimca@427
|
2724 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
MMOSimca@427
|
2725 elseif loot_type == "currency" then
|
mmosimca@496
|
2726 local currency_id = CurrencyLinkToID(hyperlink)
|
mmosimca@496
|
2727 Debug("%s: Assigned stored currency loot data - %s - currency:%d (%d)", event_name, hyperlink, currency_id, quantity)
|
mmosimca@496
|
2728 table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
|
MMOSimca@427
|
2729 end
|
jcallahan@317
|
2730 end
|
jcallahan@317
|
2731
|
MMOSimca@427
|
2732 if not boss_loot_toasting[raid_boss_id] then
|
MMOSimca@427
|
2733 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
MMOSimca@427
|
2734 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
|
jcallahan@307
|
2735 end
|
MMOSimca@427
|
2736 else
|
MMOSimca@427
|
2737 Debug("%s: NPC is nil, but we have stored loot data...", event_name)
|
jcallahan@307
|
2738 end
|
jcallahan@307
|
2739 end
|
jcallahan@307
|
2740
|
jcallahan@307
|
2741 ClearLootToastData()
|
MMOSimca@427
|
2742 killed_boss_id_timer_handle = C_Timer.NewTimer(5, ClearKilledBossID)
|
jcallahan@306
|
2743 end
|
jcallahan@306
|
2744
|
jcallahan@306
|
2745
|
jcallahan@306
|
2746 function WDP:UNIT_SPELLCAST_SUCCEEDED(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
|
jcallahan@306
|
2747 if unit_id ~= "player" then
|
jcallahan@306
|
2748 return
|
jcallahan@306
|
2749 end
|
jcallahan@306
|
2750 private.tracked_line = nil
|
jcallahan@306
|
2751 private.previous_spell_id = spell_id
|
jcallahan@306
|
2752
|
MMOSimca@393
|
2753 -- For spells cast when Logging
|
MMOSimca@345
|
2754 if private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id] then
|
MMOSimca@345
|
2755 last_timber_spell_id = spell_id
|
MMOSimca@351
|
2756 UpdateDBEntryLocation("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id]))
|
MMOSimca@345
|
2757 return
|
MMOSimca@345
|
2758 end
|
MMOSimca@345
|
2759
|
MMOSimca@393
|
2760 -- For spells cast by items that always trigger loot toasts
|
MMOSimca@381
|
2761 if private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id] then
|
jcallahan@306
|
2762 ClearKilledBossID()
|
jcallahan@306
|
2763 ClearLootToastContainerID()
|
jcallahan@307
|
2764 ClearLootToastData()
|
jcallahan@306
|
2765
|
MMOSimca@387
|
2766 loot_toast_container_id = private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
|
MMOSimca@383
|
2767 loot_toast_container_timer_handle = C_Timer.NewTimer(1, ClearLootToastContainerID) -- we need to assign a handle here to cancel it later
|
MMOSimca@345
|
2768 return
|
jcallahan@306
|
2769 end
|
jcallahan@306
|
2770
|
MMOSimca@393
|
2771 -- For spells cast by items that don't usually trigger loot toasts
|
catherton@473
|
2772 if not block_chat_loot_data and (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id] or (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id] and private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID])) then
|
MMOSimca@347
|
2773 -- Set up timer
|
MMOSimca@393
|
2774 ClearChatLootData()
|
MMOSimca@393
|
2775 Debug("%s: Beginning chat-based loot timer for spellID %d", event_name, spell_id)
|
MMOSimca@411
|
2776 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
|
catherton@473
|
2777 if (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id] and private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID]) then
|
catherton@473
|
2778 chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID]
|
MMOSimca@454
|
2779 else
|
MMOSimca@454
|
2780 chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
|
MMOSimca@454
|
2781 end
|
MMOSimca@347
|
2782 return
|
MMOSimca@347
|
2783 end
|
MMOSimca@347
|
2784
|
mmosimca@520
|
2785 -- For Ephemeral Crystals (uses a combination of mouseover text and a 'Update Interactions' spell cast to detect the object - this is incredibly hacky but there is no alternative)
|
mmosimca@520
|
2786 local text = _G["GameTooltipTextLeft1"] and _G["GameTooltipTextLeft1"]:GetText() or nil
|
mmosimca@520
|
2787 if spell_id == SPELL_ID_UPDATE_INTERACTIONS and text and text == "Ephemeral Crystal" then
|
mmosimca@522
|
2788 Debug("%s: Detected location for an Ephemeral Crystal.", event_name)
|
mmosimca@520
|
2789 for index = 1, #private.EPHEMERAL_CRYSTAL_OBJECT_IDS do
|
mmosimca@520
|
2790 UpdateDBEntryLocation("objects", private.EPHEMERAL_CRYSTAL_OBJECT_IDS[index])
|
mmosimca@520
|
2791 end
|
mmosimca@520
|
2792 end
|
mmosimca@520
|
2793
|
jcallahan@306
|
2794 if anvil_spell_ids[spell_id] then
|
jcallahan@306
|
2795 UpdateDBEntryLocation("objects", OBJECT_ID_ANVIL)
|
jcallahan@306
|
2796 elseif forge_spell_ids[spell_id] then
|
jcallahan@306
|
2797 UpdateDBEntryLocation("objects", OBJECT_ID_FORGE)
|
jcallahan@306
|
2798 elseif spell_name:match("^Harvest.+") then
|
jcallahan@306
|
2799 killed_npc_id = current_target_id
|
MMOSimca@343
|
2800 private.harvesting = true -- Used to track which NPCs can be harvested (can we get this from CreatureCache instead?)
|
jcallahan@306
|
2801 end
|
jcallahan@306
|
2802 end
|
jcallahan@0
|
2803
|
jcallahan@90
|
2804
|
jcallahan@1
|
2805 function WDP:HandleSpellFailure(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
|
jcallahan@1
|
2806 if unit_id ~= "player" then
|
jcallahan@1
|
2807 return
|
jcallahan@1
|
2808 end
|
jcallahan@0
|
2809
|
jcallahan@1
|
2810 if private.tracked_line == spell_line then
|
jcallahan@1
|
2811 private.tracked_line = nil
|
jcallahan@1
|
2812 end
|
jcallahan@147
|
2813 table.wipe(current_action)
|
jcallahan@0
|
2814 end
|
jcallahan@90
|
2815
|
jcallahan@90
|
2816
|
jcallahan@90
|
2817 do
|
jcallahan@90
|
2818 local function SetUnitField(field, required_type)
|
jcallahan@90
|
2819 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@90
|
2820
|
jcallahan@90
|
2821 if not unit_idnum or (required_type and unit_type ~= required_type) then
|
jcallahan@90
|
2822 return
|
jcallahan@90
|
2823 end
|
jcallahan@90
|
2824
|
jcallahan@171
|
2825 if UnitTypeIsNPC(unit_type) then
|
jcallahan@90
|
2826 NPCEntry(unit_idnum)[field] = true
|
jcallahan@90
|
2827 elseif unit_type == private.UNIT_TYPES.OBJECT then
|
jcallahan@90
|
2828 DBEntry("objects", unit_idnum)[field] = true
|
jcallahan@93
|
2829 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@90
|
2830 end
|
jcallahan@90
|
2831 end
|
jcallahan@90
|
2832
|
jcallahan@90
|
2833
|
jcallahan@90
|
2834 function WDP:AUCTION_HOUSE_SHOW(event_name)
|
MMOSimca@436
|
2835 WDP:StopChatLootRecording(event_name)
|
jcallahan@90
|
2836 SetUnitField("auctioneer", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2837 end
|
jcallahan@90
|
2838
|
jcallahan@90
|
2839
|
MMOSimca@581
|
2840 -- manager_frame_id is 4 in case we need to merge this into that event
|
jcallahan@90
|
2841 function WDP:BANKFRAME_OPENED(event_name)
|
MMOSimca@436
|
2842 WDP:StopChatLootRecording(event_name)
|
jcallahan@90
|
2843 SetUnitField("banker", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2844 end
|
jcallahan@90
|
2845
|
jcallahan@90
|
2846
|
jcallahan@90
|
2847 function WDP:BATTLEFIELDS_SHOW(event_name)
|
jcallahan@90
|
2848 SetUnitField("battlemaster", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2849 end
|
jcallahan@90
|
2850
|
jcallahan@90
|
2851
|
jcallahan@323
|
2852 local GOSSIP_SHOW_FUNCS = {
|
jcallahan@323
|
2853 [private.UNIT_TYPES.NPC] = function(unit_idnum)
|
MMOSimca@581
|
2854 local gossip_options = { _G.C_GossipInfo.GetOptions() }
|
jcallahan@323
|
2855
|
jcallahan@323
|
2856 for index = 2, #gossip_options, 2 do
|
jcallahan@323
|
2857 if gossip_options[index] == "binder" then
|
jcallahan@323
|
2858 SetUnitField("innkeeper", private.UNIT_TYPES.NPC)
|
jcallahan@323
|
2859 return
|
jcallahan@323
|
2860 end
|
jcallahan@323
|
2861 end
|
jcallahan@323
|
2862 end,
|
jcallahan@323
|
2863 [private.UNIT_TYPES.OBJECT] = function(unit_idnum)
|
jcallahan@323
|
2864 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@323
|
2865 end,
|
jcallahan@323
|
2866 }
|
jcallahan@323
|
2867
|
jcallahan@323
|
2868
|
MMOSimca@581
|
2869 -- manager_frame_id is 3 in case we need to merge this into that event
|
jcallahan@92
|
2870 function WDP:GOSSIP_SHOW(event_name)
|
MMOSimca@436
|
2871 WDP:StopChatLootRecording(event_name)
|
jcallahan@323
|
2872 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@323
|
2873 if not unit_idnum then
|
jcallahan@323
|
2874 return
|
jcallahan@323
|
2875 end
|
jcallahan@323
|
2876
|
jcallahan@323
|
2877 if GOSSIP_SHOW_FUNCS[unit_type] then
|
jcallahan@323
|
2878 GOSSIP_SHOW_FUNCS[unit_type](unit_idnum)
|
jcallahan@90
|
2879 end
|
jcallahan@90
|
2880 end
|
jcallahan@90
|
2881
|
jcallahan@90
|
2882
|
MMOSimca@581
|
2883 -- manager_frame_id is 10 in case we need to merge this into that event
|
jcallahan@93
|
2884 function WDP:GUILDBANKFRAME_OPENED(event_name)
|
MMOSimca@436
|
2885 WDP:StopChatLootRecording(event_name)
|
jcallahan@93
|
2886 SetUnitField("guild_bank", private.UNIT_TYPES.OBJECT)
|
jcallahan@93
|
2887 end
|
jcallahan@93
|
2888
|
jcallahan@93
|
2889
|
MMOSimca@581
|
2890 -- manager_frame_id is 6 in case we need to merge this into that event
|
jcallahan@90
|
2891 function WDP:TAXIMAP_OPENED(event_name)
|
jcallahan@90
|
2892 SetUnitField("flight_master", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2893 end
|
jcallahan@90
|
2894
|
jcallahan@90
|
2895
|
MMOSimca@581
|
2896 function WDP:PLAYER_INTERACTION_MANAGER_FRAME_SHOW(event_name, manager_frame_id)
|
MMOSimca@581
|
2897 if not manager_frame_id then
|
MMOSimca@581
|
2898 return
|
MMOSimca@581
|
2899 elseif manager_frame_id == 24 then
|
MMOSimca@581
|
2900 SetUnitField("transmogrifier", private.UNIT_TYPES.NPC)
|
MMOSimca@581
|
2901 elseif manager_frame_id == 26 then
|
MMOSimca@581
|
2902 WDP:StopChatLootRecording(event_name)
|
MMOSimca@581
|
2903 SetUnitField("void_storage", private.UNIT_TYPES.NPC)
|
MMOSimca@581
|
2904 elseif manager_frame_id == 53 then
|
MMOSimca@581
|
2905 WDP:StopChatLootRecording(event_name)
|
MMOSimca@581
|
2906 SetUnitField("item_upgrade_master", private.UNIT_TYPES.NPC)
|
MMOSimca@581
|
2907 end
|
jcallahan@90
|
2908 end
|
jcallahan@90
|
2909 end -- do-block
|