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