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@487
|
943 -- (Honor is built in to the quest; it is not a sign rewards have been loaded)
|
mmosimca@485
|
944 if not api_data_table.x or not api_data_table.y or not api_data_table.floor or not
|
mmosimca@485
|
945 (_G.GetQuestLogRewardXP(quest_id) > 0 or _G.GetNumQuestLogRewardCurrencies(quest_id) > 0
|
mmosimca@485
|
946 or _G.GetNumQuestLogRewards(quest_id) > 0 or _G.GetQuestLogRewardMoney(quest_id) > 0
|
mmosimca@487
|
947 or _G.GetQuestLogRewardArtifactXP(quest_id) > 0) then
|
mmosimca@485
|
948 return
|
mmosimca@485
|
949 end
|
mmosimca@485
|
950
|
mmosimca@485
|
951 local entry = DBEntry("world_quests", quest_id)
|
mmosimca@485
|
952
|
mmosimca@485
|
953 if entry then
|
mmosimca@485
|
954
|
mmosimca@485
|
955 -- Record location
|
mmosimca@485
|
956 entry["location"] = {}
|
mmosimca@485
|
957 entry["location"]["world_map_id"] = world_map_id
|
mmosimca@485
|
958 entry["location"]["x"] = (tonumber(api_data_table.x) or 0) * 100
|
mmosimca@485
|
959 entry["location"]["y"] = (tonumber(api_data_table.y) or 0) * 100
|
mmosimca@485
|
960 entry["location"]["floor"] = tonumber(api_data_table.floor) or 0
|
mmosimca@485
|
961
|
mmosimca@485
|
962 -- Record simple rewards (XP, money, artifact XP, honor)
|
mmosimca@485
|
963 entry["rewards"] = {}
|
mmosimca@485
|
964 entry["rewards"]["xp"] = tonumber(_G.GetQuestLogRewardXP(quest_id)) or 0
|
mmosimca@485
|
965 entry["rewards"]["money"] = tonumber(_G.GetQuestLogRewardMoney(quest_id)) or 0
|
mmosimca@485
|
966 local actualXP, scaling = _G.GetQuestLogRewardArtifactXP(quest_id)
|
mmosimca@485
|
967 entry["rewards"]["artifact_xp"] = ("%d:%d"):format(tonumber(actualXP) or 0, tonumber(scaling) or 0)
|
mmosimca@485
|
968 entry["rewards"]["honor"] = tonumber(_G.GetQuestLogRewardHonor(quest_id)) or 0
|
mmosimca@485
|
969
|
mmosimca@485
|
970 -- Record currencies
|
mmosimca@485
|
971 entry["rewards"]["currency_count"] = tonumber(_G.GetNumQuestLogRewardCurrencies(quest_id)) or 0
|
mmosimca@485
|
972
|
mmosimca@485
|
973 if entry["rewards"]["currency_count"] > 0 then
|
mmosimca@485
|
974
|
mmosimca@485
|
975 -- Create currency rewards sub-table and fill
|
mmosimca@485
|
976 entry["rewards"]["currencies"] = {}
|
mmosimca@485
|
977 for i = 1, entry["rewards"]["currency_count"] do
|
mmosimca@485
|
978 local name, texture_path, quantity = _G.GetQuestLogRewardCurrencyInfo(i, quest_id)
|
mmosimca@485
|
979 local currency_texture = texture_path:match("[^\\]+$"):lower()
|
mmosimca@485
|
980 table.insert(entry["rewards"]["currencies"], ("%d:%s"):format(quantity, currency_texture))
|
mmosimca@485
|
981 end
|
mmosimca@485
|
982 end
|
mmosimca@485
|
983
|
mmosimca@485
|
984 -- Record items
|
mmosimca@485
|
985 entry["rewards"]["item_count"] = tonumber(_G.GetNumQuestLogRewards(quest_id)) or 0
|
mmosimca@485
|
986
|
mmosimca@485
|
987 if entry["rewards"]["item_count"] > 0 then
|
mmosimca@485
|
988
|
mmosimca@485
|
989 -- Create item rewards sub-table and fill
|
mmosimca@485
|
990 entry["rewards"]["items"] = {}
|
mmosimca@485
|
991 for i = 1, entry["rewards"]["item_count"] do
|
mmosimca@485
|
992 local item_name, item_texture, quantity, quality, is_usable, item_id = _G.GetQuestLogRewardInfo(i, quest_id)
|
mmosimca@485
|
993 table.insert(entry["rewards"]["items"], ("%d:%d"):format(item_id, quantity))
|
mmosimca@485
|
994 end
|
mmosimca@485
|
995 end
|
mmosimca@485
|
996
|
mmosimca@485
|
997 -- Record time remaining
|
mmosimca@485
|
998 entry["estimated_end_time"] = _G.GetServerTime() + ((_G.C_TaskQuest.GetQuestTimeLeftMinutes(quest_id) or 0) * 60)
|
mmosimca@485
|
999 end
|
mmosimca@485
|
1000 end
|
mmosimca@485
|
1001
|
mmosimca@485
|
1002
|
mmosimca@485
|
1003 function WDP:ProcessWorldQuests()
|
mmosimca@485
|
1004 -- Ignore if player is low level
|
mmosimca@485
|
1005 if _G.UnitLevel("player") ~= 110 then return end
|
mmosimca@485
|
1006
|
mmosimca@485
|
1007 local current_world_map_id = _G.GetCurrentMapAreaID()
|
mmosimca@485
|
1008
|
mmosimca@485
|
1009 -- Iterate over known World Quest maps
|
mmosimca@485
|
1010 for i = 1, #private.WORLD_QUEST_MAP_IDS do
|
mmosimca@485
|
1011 local world_map_id = private.WORLD_QUEST_MAP_IDS[i]
|
mmosimca@485
|
1012
|
mmosimca@485
|
1013 -- Only bother checking the API if the world map in question is currently displayed OR its continent is currently displayed
|
mmosimca@485
|
1014 if current_world_map_id == WORLD_MAP_ID_BROKEN_ISLES or current_world_map_id == world_map_id then
|
mmosimca@485
|
1015
|
mmosimca@485
|
1016 -- Get data for World Quests on map
|
mmosimca@485
|
1017 local api_data = _G.C_TaskQuest.GetQuestsForPlayerByMapID(world_map_id)
|
mmosimca@485
|
1018
|
mmosimca@485
|
1019 -- Iterate over the questIDs for each map, doing preload reward requests and creating SavedVariables entries
|
mmosimca@485
|
1020 if api_data and type(api_data) == "table" and #api_data > 0 then
|
mmosimca@485
|
1021 for j = 1, #api_data do
|
mmosimca@485
|
1022 local current_data = api_data[j]
|
mmosimca@485
|
1023
|
mmosimca@485
|
1024 -- Check if we had a valid API table returned to us
|
mmosimca@485
|
1025 if current_data and type(current_data) == "table" and current_data["questId"] then
|
mmosimca@485
|
1026 local quest_id = tonumber(current_data["questId"]) or 0
|
mmosimca@485
|
1027
|
mmosimca@485
|
1028 -- Check if we have quest data
|
mmosimca@485
|
1029 if _G.HaveQuestData(quest_id) then
|
mmosimca@485
|
1030 local tag_id, tag_name, world_quest_type, rarity, is_elite, tradeskill_line_index = _G.GetQuestTagInfo(quest_id)
|
mmosimca@485
|
1031
|
mmosimca@485
|
1032 -- Check for valid questID and whether or not it is a World Quest
|
mmosimca@485
|
1033 if quest_id > 0 and world_quest_type ~= nil then
|
mmosimca@485
|
1034 _G.C_TaskQuest.RequestPreloadRewardData(quest_id)
|
mmosimca@485
|
1035 RecordWorldQuestData(world_map_id, quest_id, current_data)
|
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 end
|
mmosimca@485
|
1044
|
mmosimca@485
|
1045
|
MMOSimca@340
|
1046 local function RecordItemData(item_id, item_link, process_bonus_ids, durability)
|
jcallahan@331
|
1047 local _, _, item_string = item_link:find("^|%x+|H(.+)|h%[.+%]")
|
jcallahan@219
|
1048 local item
|
jcallahan@0
|
1049
|
jcallahan@191
|
1050 if item_string then
|
MMOSimca@338
|
1051 local item_results = { (":"):split(item_string) }
|
MMOSimca@338
|
1052
|
MMOSimca@460
|
1053 local suffix_id = tonumber(item_results[8]) or 0
|
MMOSimca@462
|
1054 local unique_id = tonumber(item_results[9]) or 0
|
MMOSimca@447
|
1055 --local level = tonumber(item_results[10])
|
MMOSimca@460
|
1056 --local specialization_id = tonumber(item_results[11])
|
catherton@469
|
1057 --local upgrade_type_id = tonumber(item_results[12])
|
MMOSimca@460
|
1058 local instance_difficulty_id = tonumber(item_results[13]) or 0
|
MMOSimca@460
|
1059 local num_bonus_ids = tonumber(item_results[14]) or 0
|
catherton@471
|
1060 -- 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
|
1061 local upgrade_value = tonumber(item_results[15 + num_bonus_ids]) or 0
|
catherton@465
|
1062
|
mmosimca@484
|
1063 local unk_item_field_1 = tonumber(item_results[16 + num_bonus_ids]) or 0
|
mmosimca@484
|
1064 local unk_item_field_2 = tonumber(item_results[17 + num_bonus_ids]) or 0
|
mmosimca@484
|
1065 --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
|
1066 --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
|
1067
|
MMOSimca@460
|
1068 -- If there is anything special (non-zero) for this item then we need to make note of everything
|
catherton@471
|
1069 if math.max(suffix_id, instance_difficulty_id, num_bonus_ids, upgrade_value) ~= 0 then
|
MMOSimca@460
|
1070 item = DBEntry("items", item_id)
|
MMOSimca@460
|
1071 item.suffix_id = suffix_id
|
MMOSimca@460
|
1072 item.unique_id = bit.band(unique_id, 0xFFFF)
|
MMOSimca@460
|
1073 item.instance_difficulty_id = instance_difficulty_id
|
catherton@471
|
1074 item.upgrade_value = upgrade_value
|
MMOSimca@460
|
1075
|
MMOSimca@460
|
1076 if process_bonus_ids then
|
MMOSimca@460
|
1077
|
MMOSimca@460
|
1078 -- Get ready for bonus IDs
|
MMOSimca@384
|
1079 if not item.seen_bonuses then
|
MMOSimca@384
|
1080 item.seen_bonuses = {}
|
MMOSimca@372
|
1081 end
|
catherton@465
|
1082
|
MMOSimca@460
|
1083 if num_bonus_ids > 0 then
|
MMOSimca@460
|
1084 -- We want the bonus ID combo output to be in the form ["bonusID1:bonusID2:bonusID3"] = true
|
MMOSimca@460
|
1085 -- And sorted numerically with the smallest bonusID first
|
MMOSimca@460
|
1086 local sorted_bonus_string = ""
|
MMOSimca@460
|
1087 local min_bonus_id_array = {}
|
MMOSimca@460
|
1088 for iterations = 1, num_bonus_ids do
|
MMOSimca@460
|
1089 -- Find minimum of this iteration
|
MMOSimca@460
|
1090 local min_bonus_id = 100000
|
MMOSimca@460
|
1091 for bonus_index = 1, num_bonus_ids do
|
MMOSimca@460
|
1092 local temp_bonus_id = tonumber(item_results[14 + bonus_index])
|
MMOSimca@460
|
1093 if temp_bonus_id and (not min_bonus_id_array[temp_bonus_id]) and (temp_bonus_id < min_bonus_id) then
|
MMOSimca@460
|
1094 min_bonus_id = temp_bonus_id
|
MMOSimca@460
|
1095 end
|
MMOSimca@460
|
1096 end
|
MMOSimca@460
|
1097
|
MMOSimca@460
|
1098 -- Keep track of already processed IDs
|
MMOSimca@460
|
1099 min_bonus_id_array[min_bonus_id] = true
|
MMOSimca@460
|
1100
|
MMOSimca@460
|
1101 -- Build string
|
MMOSimca@460
|
1102 if iterations == 1 then
|
MMOSimca@460
|
1103 sorted_bonus_string = sorted_bonus_string .. tostring(min_bonus_id)
|
MMOSimca@460
|
1104 else
|
MMOSimca@460
|
1105 sorted_bonus_string = sorted_bonus_string .. ":" .. tostring(min_bonus_id)
|
MMOSimca@460
|
1106 end
|
MMOSimca@384
|
1107 end
|
MMOSimca@460
|
1108
|
MMOSimca@460
|
1109 item.seen_bonuses[sorted_bonus_string] = true
|
MMOSimca@460
|
1110 Debug("RecordItemData: Recorded bonus IDs %s for item %d.", sorted_bonus_string, item_id)
|
MMOSimca@384
|
1111 else
|
MMOSimca@460
|
1112 item.seen_bonuses["0"] = true
|
MMOSimca@384
|
1113 end
|
MMOSimca@329
|
1114 end
|
jcallahan@191
|
1115 end
|
jcallahan@0
|
1116 end
|
jcallahan@212
|
1117
|
jcallahan@212
|
1118 if durability and durability > 0 then
|
jcallahan@219
|
1119 item = item or DBEntry("items", item_id)
|
jcallahan@212
|
1120 item.durability = durability
|
jcallahan@212
|
1121 end
|
jcallahan@0
|
1122 end
|
jcallahan@0
|
1123
|
jcallahan@0
|
1124
|
jcallahan@187
|
1125 function WDP:ProcessItems()
|
jcallahan@187
|
1126 for slot_index = _G.INVSLOT_FIRST_EQUIPPED, _G.INVSLOT_LAST_EQUIPPED do
|
jcallahan@1
|
1127 local item_id = _G.GetInventoryItemID("player", slot_index)
|
jcallahan@0
|
1128
|
jcallahan@0
|
1129 if item_id and item_id > 0 then
|
jcallahan@1
|
1130 local _, max_durability = _G.GetInventoryItemDurability(slot_index)
|
MMOSimca@340
|
1131 RecordItemData(item_id, _G.GetInventoryItemLink("player", slot_index), false, max_durability)
|
jcallahan@0
|
1132 end
|
jcallahan@0
|
1133 end
|
jcallahan@0
|
1134
|
jcallahan@0
|
1135 for bag_index = 0, _G.NUM_BAG_SLOTS do
|
jcallahan@0
|
1136 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do
|
jcallahan@1
|
1137 local item_id = _G.GetContainerItemID(bag_index, slot_index)
|
jcallahan@0
|
1138
|
jcallahan@0
|
1139 if item_id and item_id > 0 then
|
jcallahan@1
|
1140 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index)
|
MMOSimca@340
|
1141 RecordItemData(item_id, _G.GetContainerItemLink(bag_index, slot_index), false, max_durability)
|
jcallahan@0
|
1142 end
|
jcallahan@0
|
1143 end
|
jcallahan@0
|
1144 end
|
jcallahan@0
|
1145 end
|
jcallahan@0
|
1146
|
jcallahan@118
|
1147
|
jcallahan@215
|
1148 local TargetedNPC
|
jcallahan@118
|
1149 do
|
jcallahan@118
|
1150 local GENDER_NAMES = {
|
jcallahan@118
|
1151 "UNKNOWN",
|
jcallahan@118
|
1152 "MALE",
|
jcallahan@118
|
1153 "FEMALE",
|
jcallahan@118
|
1154 }
|
jcallahan@118
|
1155
|
jcallahan@118
|
1156
|
jcallahan@118
|
1157 local REACTION_NAMES = {
|
jcallahan@118
|
1158 "HATED",
|
jcallahan@118
|
1159 "HOSTILE",
|
jcallahan@118
|
1160 "UNFRIENDLY",
|
jcallahan@118
|
1161 "NEUTRAL",
|
jcallahan@118
|
1162 "FRIENDLY",
|
jcallahan@118
|
1163 "HONORED",
|
jcallahan@118
|
1164 "REVERED",
|
jcallahan@118
|
1165 "EXALTED",
|
jcallahan@118
|
1166 }
|
jcallahan@118
|
1167
|
jcallahan@118
|
1168
|
jcallahan@118
|
1169 local POWER_TYPE_NAMES = {
|
jcallahan@118
|
1170 ["0"] = "MANA",
|
jcallahan@118
|
1171 ["1"] = "RAGE",
|
jcallahan@118
|
1172 ["2"] = "FOCUS",
|
jcallahan@118
|
1173 ["3"] = "ENERGY",
|
jcallahan@118
|
1174 ["6"] = "RUNIC_POWER",
|
jcallahan@118
|
1175 }
|
jcallahan@118
|
1176
|
jcallahan@118
|
1177
|
jcallahan@215
|
1178 function TargetedNPC()
|
jcallahan@118
|
1179 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or currently_drunk then
|
jcallahan@118
|
1180 current_target_id = nil
|
jcallahan@118
|
1181 return
|
jcallahan@118
|
1182 end
|
jcallahan@118
|
1183 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("target"))
|
jcallahan@118
|
1184
|
jcallahan@171
|
1185 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@118
|
1186 return
|
jcallahan@118
|
1187 end
|
jcallahan@118
|
1188 current_target_id = unit_idnum
|
jcallahan@118
|
1189
|
jcallahan@118
|
1190 local npc = NPCEntry(unit_idnum)
|
jcallahan@118
|
1191 local _, class_token = _G.UnitClass("target")
|
jcallahan@118
|
1192 npc.class = class_token
|
jcallahan@118
|
1193 npc.faction = UnitFactionStanding("target")
|
jcallahan@118
|
1194 npc.genders = npc.genders or {}
|
jcallahan@118
|
1195 npc.genders[GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true
|
jcallahan@118
|
1196 npc.is_pvp = _G.UnitIsPVP("target") and true or nil
|
jcallahan@118
|
1197 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), REACTION_NAMES[_G.UnitReaction("player", "target")])
|
jcallahan@118
|
1198
|
jcallahan@248
|
1199 local encounter_data = npc:EncounterData(InstanceDifficultyToken()).stats
|
jcallahan@118
|
1200 local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
|
jcallahan@250
|
1201 local level_data = encounter_data[npc_level]
|
jcallahan@250
|
1202
|
jcallahan@250
|
1203 if not level_data then
|
jcallahan@250
|
1204 level_data = {}
|
jcallahan@250
|
1205 encounter_data[npc_level] = level_data
|
jcallahan@250
|
1206 end
|
jcallahan@257
|
1207 level_data.max_health = level_data.max_health or _G.UnitHealthMax("target")
|
jcallahan@257
|
1208
|
jcallahan@257
|
1209 if not level_data.power then
|
MMOSimca@337
|
1210 local max_power = _G.UnitPowerMax("target")
|
jcallahan@257
|
1211
|
jcallahan@257
|
1212 if max_power > 0 then
|
jcallahan@257
|
1213 local power_type = _G.UnitPowerType("target")
|
jcallahan@312
|
1214 level_data.power = ("%s:%d"):format(POWER_TYPE_NAMES[tostring(power_type)] or power_type, max_power)
|
jcallahan@257
|
1215 end
|
jcallahan@118
|
1216 end
|
jcallahan@118
|
1217 name_to_id_map[_G.UnitName("target")] = unit_idnum
|
jcallahan@118
|
1218 return npc, unit_idnum
|
jcallahan@118
|
1219 end
|
jcallahan@118
|
1220 end -- do-block
|
jcallahan@118
|
1221
|
jcallahan@118
|
1222
|
jcallahan@113
|
1223 do
|
jcallahan@113
|
1224 local COORD_MAX = 5
|
jcallahan@0
|
1225
|
jcallahan@113
|
1226 function WDP:UpdateTargetLocation()
|
catherton@480
|
1227 if currently_drunk or not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or (_G.UnitIsTapDenied("target") and not _G.UnitIsDead("target")) then
|
jcallahan@2
|
1228 return
|
jcallahan@2
|
1229 end
|
jcallahan@113
|
1230
|
jcallahan@113
|
1231 for index = 1, 4 do
|
jcallahan@113
|
1232 if not _G.CheckInteractDistance("target", index) then
|
jcallahan@113
|
1233 return
|
jcallahan@113
|
1234 end
|
jcallahan@113
|
1235 end
|
jcallahan@215
|
1236 local npc = TargetedNPC()
|
jcallahan@113
|
1237
|
jcallahan@113
|
1238 if not npc then
|
jcallahan@113
|
1239 return
|
jcallahan@113
|
1240 end
|
jcallahan@113
|
1241 local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
|
MMOSimca@328
|
1242 if not (zone_name and area_id and x and y and map_level) then
|
catherton@468
|
1243 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
|
1244 return
|
MMOSimca@328
|
1245 end
|
jcallahan@248
|
1246 local npc_data = npc:EncounterData(difficulty_token).stats[("level_%d"):format(_G.UnitLevel("target"))]
|
jcallahan@113
|
1247 local zone_token = ("%s:%d"):format(zone_name, area_id)
|
jcallahan@118
|
1248 npc_data.locations = npc_data.locations or {} -- TODO: Fix this. It is broken. Possibly something to do with the timed updates.
|
jcallahan@113
|
1249
|
jcallahan@113
|
1250 local zone_data = npc_data.locations[zone_token]
|
jcallahan@113
|
1251
|
jcallahan@113
|
1252 if not zone_data then
|
jcallahan@113
|
1253 zone_data = {}
|
jcallahan@113
|
1254 npc_data.locations[zone_token] = zone_data
|
jcallahan@113
|
1255 end
|
jcallahan@113
|
1256
|
jcallahan@113
|
1257 for location_token in pairs(zone_data) do
|
jcallahan@113
|
1258 local loc_level, loc_x, loc_y = (":"):split(location_token)
|
jcallahan@113
|
1259 loc_level = tonumber(loc_level)
|
jcallahan@113
|
1260
|
jcallahan@113
|
1261 if map_level == loc_level and math.abs(x - loc_x) <= COORD_MAX and math.abs(y - loc_y) <= COORD_MAX then
|
jcallahan@113
|
1262 return
|
jcallahan@113
|
1263 end
|
jcallahan@113
|
1264 end
|
jcallahan@141
|
1265 zone_data[("%d:%d:%d"):format(map_level, x, y)] = true
|
jcallahan@2
|
1266 end
|
jcallahan@113
|
1267 end -- do-block
|
jcallahan@2
|
1268
|
jcallahan@118
|
1269
|
MMOSimca@412
|
1270 function WDP:HandleBadChatLootData(...)
|
MMOSimca@398
|
1271 ClearChatLootData()
|
MMOSimca@398
|
1272 end
|
MMOSimca@398
|
1273
|
MMOSimca@398
|
1274
|
MMOSimca@420
|
1275 -- EVENT HANDLERS -----------------------------------------------------
|
MMOSimca@420
|
1276
|
MMOSimca@436
|
1277 -- 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
|
1278 function WDP:StopChatLootRecording(event_name)
|
MMOSimca@436
|
1279 if not block_chat_loot_data then
|
MMOSimca@439
|
1280 Debug("%s: Pausing chat-based loot recording.", event_name)
|
MMOSimca@436
|
1281 ClearChatLootData()
|
MMOSimca@436
|
1282 block_chat_loot_data = true
|
MMOSimca@436
|
1283 end
|
MMOSimca@436
|
1284 end
|
MMOSimca@436
|
1285
|
MMOSimca@436
|
1286
|
MMOSimca@436
|
1287 function WDP:ResumeChatLootRecording(event_name)
|
MMOSimca@436
|
1288 if block_chat_loot_data then
|
MMOSimca@439
|
1289 Debug("%s: Resuming chat-based loot recording.", event_name)
|
MMOSimca@436
|
1290 block_chat_loot_data = false
|
MMOSimca@436
|
1291 end
|
MMOSimca@436
|
1292 end
|
MMOSimca@436
|
1293
|
MMOSimca@436
|
1294
|
mmosimca@485
|
1295 -- 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
|
1296 function WDP:WORLD_MAP_UPATE(event_name)
|
mmosimca@485
|
1297 if _G.GetCurrentMapAreaID() == WORLD_MAP_ID_BROKEN_ISLES and _G.GetServerTime() > (world_quest_event_timestamp + DELAY_PROCESS_WORLD_QUESTS) then
|
mmosimca@485
|
1298 world_quest_event_timestamp = _G.GetServerTime()
|
mmosimca@485
|
1299 WDP:ProcessWorldQuests()
|
mmosimca@485
|
1300 end
|
mmosimca@485
|
1301 end
|
mmosimca@485
|
1302
|
mmosimca@485
|
1303
|
MMOSimca@408
|
1304 -- 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
|
1305 function WDP:BONUS_ROLL_RESULT(event_name)
|
MMOSimca@408
|
1306 Debug("%s: Bonus roll detected; stopping loot recording for this boss to avoid recording bonus loot.", event_name)
|
MMOSimca@408
|
1307 ClearKilledBossID()
|
MMOSimca@408
|
1308 ClearLootToastContainerID()
|
MMOSimca@408
|
1309 end
|
MMOSimca@408
|
1310
|
MMOSimca@408
|
1311
|
jcallahan@90
|
1312 function WDP:BLACK_MARKET_ITEM_UPDATE(event_name)
|
jcallahan@243
|
1313 if not ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@243
|
1314 return
|
jcallahan@243
|
1315 end
|
jcallahan@282
|
1316 local num_items = _G.C_BlackMarket.GetNumItems() or 0
|
jcallahan@56
|
1317
|
jcallahan@56
|
1318 for index = 1, num_items do
|
jcallahan@56
|
1319 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
|
1320
|
jcallahan@56
|
1321 if item_link then
|
jcallahan@56
|
1322 DBEntry("items", ItemLinkToID(item_link)).black_market = seller_name or "UNKNOWN"
|
jcallahan@56
|
1323 end
|
jcallahan@56
|
1324 end
|
jcallahan@56
|
1325 end
|
jcallahan@56
|
1326
|
jcallahan@56
|
1327
|
jcallahan@298
|
1328 local function UpdateUnitPet(unit_guid, unit_id)
|
jcallahan@246
|
1329 local current_pet_guid = group_owner_guids_to_pet_guids[unit_guid]
|
jcallahan@246
|
1330
|
jcallahan@246
|
1331 if current_pet_guid then
|
jcallahan@246
|
1332 group_owner_guids_to_pet_guids[unit_guid] = nil
|
jcallahan@246
|
1333 group_pet_guids[current_pet_guid] = nil
|
jcallahan@246
|
1334 end
|
jcallahan@246
|
1335 local pet_guid = _G.UnitGUID(unit_id .. "pet")
|
jcallahan@246
|
1336
|
jcallahan@246
|
1337 if pet_guid then
|
jcallahan@296
|
1338 group_owner_guids_to_pet_guids[unit_guid] = pet_guid
|
jcallahan@246
|
1339 group_pet_guids[pet_guid] = true
|
jcallahan@246
|
1340 end
|
jcallahan@246
|
1341 end
|
jcallahan@246
|
1342
|
jcallahan@246
|
1343
|
jcallahan@298
|
1344 function WDP:GROUP_ROSTER_UPDATE(event_name)
|
jcallahan@298
|
1345 local is_raid = _G.IsInRaid()
|
jcallahan@298
|
1346 local unit_type = is_raid and "raid" or "party"
|
jcallahan@298
|
1347 local group_size = is_raid and _G.GetNumGroupMembers() or _G.GetNumSubgroupMembers()
|
jcallahan@298
|
1348
|
jcallahan@299
|
1349 table.wipe(group_member_guids)
|
jcallahan@298
|
1350
|
jcallahan@298
|
1351 for index = 1, group_size do
|
jcallahan@298
|
1352 local unit_id = unit_type .. index
|
jcallahan@298
|
1353 local unit_guid = _G.UnitGUID(unit_id)
|
jcallahan@298
|
1354
|
jcallahan@299
|
1355 group_member_guids[unit_guid] = true
|
jcallahan@298
|
1356 UpdateUnitPet(unit_guid, unit_id)
|
jcallahan@298
|
1357 end
|
jcallahan@299
|
1358 group_member_guids[PLAYER_GUID] = true
|
jcallahan@298
|
1359 end
|
jcallahan@298
|
1360
|
jcallahan@298
|
1361
|
jcallahan@298
|
1362 function WDP:UNIT_PET(event_name, unit_id)
|
jcallahan@298
|
1363 UpdateUnitPet(_G.UnitGUID(unit_id), unit_id)
|
jcallahan@298
|
1364 end
|
jcallahan@298
|
1365
|
jcallahan@298
|
1366
|
MMOSimca@375
|
1367 function WDP:SHOW_LOOT_TOAST(event_name, loot_type, item_link, quantity, spec_ID, sex_ID, is_personal, loot_source)
|
jcallahan@312
|
1368 if not loot_type or (loot_type ~= "item" and loot_type ~= "money" and loot_type ~= "currency") then
|
jcallahan@306
|
1369 Debug("%s: loot_type is %s. Item link is %s, and quantity is %d.", event_name, loot_type, item_link, quantity)
|
jcallahan@306
|
1370 return
|
jcallahan@306
|
1371 end
|
MMOSimca@372
|
1372
|
MMOSimca@372
|
1373 -- Need information on the most recent args, so using this complete debug statement for now
|
MMOSimca@375
|
1374 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
|
1375
|
MMOSimca@355
|
1376 -- Handle Garrison cache specially
|
MMOSimca@422
|
1377 if loot_source and (loot_source == LOOT_SOURCE_ID_GARRISON_CACHE) and last_garrison_cache_object_id then
|
MMOSimca@355
|
1378 -- Record location data for cache
|
MMOSimca@355
|
1379 UpdateDBEntryLocation("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
|
MMOSimca@355
|
1380
|
MMOSimca@355
|
1381 -- Add drop data
|
MMOSimca@355
|
1382 local currency_texture = CurrencyLinkToTexture(item_link)
|
MMOSimca@355
|
1383 if currency_texture and currency_texture ~= "" then
|
MMOSimca@355
|
1384 -- Check for top level object data
|
MMOSimca@355
|
1385 local object_entry = DBEntry("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
|
MMOSimca@355
|
1386 local difficulty_token = InstanceDifficultyToken()
|
MMOSimca@355
|
1387 if object_entry[difficulty_token] then
|
MMOSimca@355
|
1388 -- Increment loot count
|
MMOSimca@355
|
1389 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
|
MMOSimca@355
|
1390
|
MMOSimca@355
|
1391 Debug("%s: %s X %d", event_name, currency_texture, quantity)
|
MMOSimca@355
|
1392 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
|
MMOSimca@355
|
1393 table.insert(object_entry[difficulty_token]["opening"], ("currency:%d:%s"):format(quantity, currency_texture))
|
MMOSimca@355
|
1394 else
|
MMOSimca@355
|
1395 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
|
1396 end
|
MMOSimca@355
|
1397 else
|
MMOSimca@355
|
1398 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link)
|
MMOSimca@355
|
1399 end
|
catherton@465
|
1400
|
MMOSimca@431
|
1401 -- Wipe object ID until future mouseover
|
MMOSimca@431
|
1402 last_garrison_cache_object_id = nil
|
MMOSimca@387
|
1403 elseif raid_boss_id then
|
MMOSimca@427
|
1404 local npc = NPCEntry(raid_boss_id)
|
MMOSimca@427
|
1405 if npc then
|
MMOSimca@427
|
1406 local loot_label = "drops"
|
MMOSimca@427
|
1407 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
|
MMOSimca@427
|
1408 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
MMOSimca@427
|
1409 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@427
|
1410
|
MMOSimca@427
|
1411 if loot_type == "item" then
|
MMOSimca@427
|
1412 local item_id = ItemLinkToID(item_link)
|
MMOSimca@427
|
1413 if item_id then
|
MMOSimca@427
|
1414 Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
|
MMOSimca@427
|
1415 RecordItemData(item_id, item_link, true)
|
MMOSimca@427
|
1416 table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@427
|
1417 else
|
MMOSimca@427
|
1418 Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
|
MMOSimca@427
|
1419 return
|
MMOSimca@427
|
1420 end
|
MMOSimca@427
|
1421 elseif loot_type == "money" then
|
MMOSimca@427
|
1422 Debug("%s: money X %d", event_name, quantity)
|
MMOSimca@427
|
1423 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
MMOSimca@427
|
1424 elseif loot_type == "currency" then
|
MMOSimca@427
|
1425 local currency_texture = CurrencyLinkToTexture(item_link)
|
MMOSimca@427
|
1426 if currency_texture and currency_texture ~= "" then
|
MMOSimca@427
|
1427 Debug("%s: %s X %d", event_name, currency_texture, quantity)
|
MMOSimca@427
|
1428 table.insert(encounter_data[loot_label], ("currency:%d:%s"):format(quantity, currency_texture))
|
MMOSimca@427
|
1429 else
|
MMOSimca@427
|
1430 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link)
|
MMOSimca@427
|
1431 return
|
MMOSimca@427
|
1432 end
|
jcallahan@312
|
1433 end
|
jcallahan@317
|
1434
|
MMOSimca@427
|
1435 if not boss_loot_toasting[raid_boss_id] then
|
MMOSimca@427
|
1436 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
MMOSimca@427
|
1437 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
|
jcallahan@312
|
1438 end
|
jcallahan@312
|
1439 end
|
MMOSimca@387
|
1440 elseif loot_toast_container_id then
|
jcallahan@305
|
1441 InitializeCurrentLoot()
|
jcallahan@305
|
1442
|
jcallahan@306
|
1443 -- Fake the loot characteristics to match that of an actual container item
|
MMOSimca@387
|
1444 current_loot.identifier = loot_toast_container_id
|
jcallahan@306
|
1445 current_loot.label = "contains"
|
jcallahan@306
|
1446 current_loot.target_type = AF.ITEM
|
jcallahan@306
|
1447
|
MMOSimca@387
|
1448 current_loot.sources[loot_toast_container_id] = current_loot.sources[loot_toast_container_id] or {}
|
jcallahan@312
|
1449
|
jcallahan@301
|
1450 if loot_type == "item" then
|
jcallahan@312
|
1451 local item_id = ItemLinkToID(item_link)
|
jcallahan@312
|
1452 if item_id then
|
jcallahan@312
|
1453 Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
|
MMOSimca@340
|
1454 RecordItemData(item_id, item_link, true)
|
MMOSimca@387
|
1455 current_loot.sources[loot_toast_container_id][item_id] = (current_loot.sources[loot_toast_container_id][item_id] or 0) + quantity
|
jcallahan@312
|
1456 else
|
jcallahan@301
|
1457 Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
|
jcallahan@312
|
1458 current_loot = nil
|
jcallahan@301
|
1459 return
|
jcallahan@301
|
1460 end
|
jcallahan@301
|
1461 elseif loot_type == "money" then
|
jcallahan@312
|
1462 Debug("%s: money X %d", event_name, quantity)
|
MMOSimca@387
|
1463 current_loot.sources[loot_toast_container_id]["money"] = (current_loot.sources[loot_toast_container_id]["money"] or 0) + quantity
|
jcallahan@312
|
1464 elseif loot_type == "currency" then
|
jcallahan@312
|
1465 local currency_texture = CurrencyLinkToTexture(item_link)
|
jcallahan@312
|
1466 if currency_texture and currency_texture ~= "" then
|
jcallahan@312
|
1467 Debug("%s: %s X %d", event_name, currency_texture, quantity)
|
jcallahan@312
|
1468 local currency_token = ("currency:%s"):format(currency_texture)
|
MMOSimca@387
|
1469 current_loot.sources[loot_toast_container_id][currency_token] = (current_loot.sources[loot_toast_container_id][currency_token] or 0) + quantity
|
jcallahan@312
|
1470 else
|
jcallahan@312
|
1471 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link)
|
jcallahan@312
|
1472 current_loot = nil
|
jcallahan@312
|
1473 return
|
jcallahan@312
|
1474 end
|
jcallahan@301
|
1475 end
|
jcallahan@312
|
1476
|
jcallahan@301
|
1477 GenericLootUpdate("items")
|
jcallahan@301
|
1478 current_loot = nil
|
MMOSimca@387
|
1479 container_loot_toasting = true -- Do not count further loots until timer expires or another container is opened
|
MMOSimca@444
|
1480 elseif loot_source and (loot_source == LOOT_SOURCE_ID_REDUNDANT) and chat_loot_timer_handle then
|
MMOSimca@444
|
1481 -- 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
|
1482 if loot_type == "currency" then
|
MMOSimca@444
|
1483 local currency_texture = CurrencyLinkToTexture(item_link)
|
MMOSimca@444
|
1484 if currency_texture and currency_texture ~= "" then
|
MMOSimca@444
|
1485 -- Verify that we're still assigning data to the right items
|
MMOSimca@444
|
1486 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
MMOSimca@444
|
1487 local currency_token = ("currency:%s"):format(currency_texture)
|
MMOSimca@444
|
1488 Debug("%s: Captured currency for chat-based loot recording. %s X %d", event_name, currency_token, quantity)
|
MMOSimca@444
|
1489 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@444
|
1490 chat_loot_data.loot[currency_token] = (chat_loot_data.loot[currency_token] or 0) + quantity
|
MMOSimca@444
|
1491 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@444
|
1492 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
|
MMOSimca@444
|
1493 ClearChatLootData()
|
MMOSimca@444
|
1494 end
|
MMOSimca@444
|
1495 else
|
MMOSimca@444
|
1496 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link)
|
MMOSimca@444
|
1497 end
|
MMOSimca@444
|
1498 -- 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
|
1499 elseif loot_type == "money" then
|
MMOSimca@424
|
1500 -- Verify that we're still assigning data to the right items
|
MMOSimca@435
|
1501 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
MMOSimca@444
|
1502 Debug("%s: Captured money for chat-based loot recording. money X %d", event_name, quantity)
|
MMOSimca@435
|
1503 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@444
|
1504 chat_loot_data.loot["money"] = (chat_loot_data.loot["money"] or 0) + quantity
|
MMOSimca@424
|
1505 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@424
|
1506 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
|
MMOSimca@424
|
1507 ClearChatLootData()
|
MMOSimca@424
|
1508 end
|
MMOSimca@424
|
1509 end
|
jcallahan@301
|
1510 else
|
jcallahan@307
|
1511 Debug("%s: NPC and Container are nil, storing loot toast data for 5 seconds.", event_name)
|
jcallahan@307
|
1512
|
jcallahan@307
|
1513 loot_toast_data = loot_toast_data or {}
|
jcallahan@312
|
1514 loot_toast_data[#loot_toast_data + 1] = { loot_type, item_link, quantity }
|
jcallahan@307
|
1515
|
MMOSimca@340
|
1516 local item_id = ItemLinkToID(item_link)
|
MMOSimca@340
|
1517 if item_id then
|
MMOSimca@340
|
1518 RecordItemData(item_id, item_link, true)
|
MMOSimca@340
|
1519 end
|
MMOSimca@340
|
1520
|
MMOSimca@383
|
1521 loot_toast_data_timer_handle = C_Timer.NewTimer(5, ClearLootToastData)
|
jcallahan@178
|
1522 end
|
jcallahan@178
|
1523 end
|
jcallahan@178
|
1524
|
jcallahan@178
|
1525
|
jcallahan@179
|
1526 do
|
MMOSimca@388
|
1527 local CHAT_MSG_CURRENCY_UPDATE_FUNCS = {
|
MMOSimca@388
|
1528 [AF.NPC] = function(currency_texture, quantity)
|
MMOSimca@388
|
1529 Debug("CHAT_MSG_CURRENCY: AF.NPC currency:%s (%d)", currency_texture, quantity)
|
MMOSimca@388
|
1530 end,
|
MMOSimca@388
|
1531 [AF.ZONE] = function(currency_texture, quantity)
|
MMOSimca@388
|
1532 local currency_token = ("currency:%s"):format(currency_texture)
|
MMOSimca@388
|
1533 Debug("CHAT_MSG_CURRENCY: AF.ZONE %s (%d)", currency_token, quantity)
|
MMOSimca@388
|
1534 InitializeCurrentLoot()
|
MMOSimca@388
|
1535 current_loot.list[1] = ("%s:%d"):format(currency_token, quantity)
|
MMOSimca@388
|
1536 GenericLootUpdate("zones")
|
MMOSimca@388
|
1537 current_loot = nil
|
MMOSimca@388
|
1538 end,
|
MMOSimca@388
|
1539 }
|
MMOSimca@388
|
1540
|
MMOSimca@388
|
1541
|
MMOSimca@388
|
1542 function WDP:CHAT_MSG_CURRENCY(event_name, message)
|
MMOSimca@388
|
1543 local category
|
MMOSimca@388
|
1544
|
MMOSimca@388
|
1545 local currency_link, quantity = deformat(message, _G.CURRENCY_GAINED_MULTIPLE)
|
MMOSimca@388
|
1546 if not currency_link then
|
MMOSimca@388
|
1547 quantity, currency_link = 1, deformat(message, _G.CURRENCY_GAINED)
|
MMOSimca@388
|
1548 end
|
MMOSimca@388
|
1549 local currency_texture = CurrencyLinkToTexture(currency_link)
|
MMOSimca@388
|
1550
|
MMOSimca@388
|
1551 if not currency_texture or currency_texture == "" then
|
MMOSimca@388
|
1552 return
|
MMOSimca@388
|
1553 end
|
MMOSimca@388
|
1554
|
MMOSimca@388
|
1555 -- Set update category
|
MMOSimca@388
|
1556 if current_action.spell_label == "FISHING" then
|
MMOSimca@388
|
1557 category = AF.ZONE
|
MMOSimca@388
|
1558 elseif raid_boss_id then
|
MMOSimca@388
|
1559 category = AF.NPC
|
MMOSimca@388
|
1560 end
|
MMOSimca@388
|
1561
|
MMOSimca@388
|
1562 -- Take action based on update category
|
MMOSimca@388
|
1563 local update_func = CHAT_MSG_CURRENCY_UPDATE_FUNCS[category]
|
MMOSimca@388
|
1564 if not category or not update_func then
|
MMOSimca@388
|
1565 return
|
MMOSimca@388
|
1566 end
|
MMOSimca@388
|
1567 update_func(currency_texture, quantity)
|
MMOSimca@388
|
1568 end
|
MMOSimca@388
|
1569
|
MMOSimca@388
|
1570
|
MMOSimca@412
|
1571 local BLACKLISTED_ITEMS = {
|
MMOSimca@412
|
1572 [114116] = true,
|
MMOSimca@412
|
1573 [114119] = true,
|
MMOSimca@412
|
1574 [114120] = true,
|
MMOSimca@412
|
1575 [116980] = true,
|
MMOSimca@412
|
1576 [120319] = true,
|
MMOSimca@412
|
1577 [120320] = true,
|
catherton@475
|
1578 [139593] = true,
|
catherton@475
|
1579 [139594] = true,
|
catherton@475
|
1580 [140590] = true,
|
MMOSimca@412
|
1581 }
|
MMOSimca@412
|
1582
|
MMOSimca@412
|
1583
|
jcallahan@179
|
1584 local CHAT_MSG_LOOT_UPDATE_FUNCS = {
|
MMOSimca@347
|
1585 [AF.ITEM] = function(item_id, quantity)
|
MMOSimca@347
|
1586 -- Verify that we're still assigning data to the right items
|
MMOSimca@435
|
1587 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
|
MMOSimca@347
|
1588 Debug("CHAT_MSG_LOOT: AF.ITEM %d (%d)", item_id, quantity)
|
MMOSimca@435
|
1589 chat_loot_data.loot = chat_loot_data.loot or {}
|
MMOSimca@435
|
1590 chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
|
MMOSimca@347
|
1591 else -- If not, cancel the timer and wipe the loot table early
|
MMOSimca@387
|
1592 Debug("CHAT_MSG_LOOT: We would have assigned the wrong loot!")
|
MMOSimca@387
|
1593 ClearChatLootData()
|
MMOSimca@347
|
1594 end
|
MMOSimca@347
|
1595 end,
|
jcallahan@179
|
1596 [AF.NPC] = function(item_id, quantity)
|
MMOSimca@345
|
1597 Debug("CHAT_MSG_LOOT: AF.NPC %d (%d)", item_id, quantity)
|
MMOSimca@345
|
1598 end,
|
MMOSimca@345
|
1599 [AF.OBJECT] = function(item_id, quantity)
|
MMOSimca@345
|
1600 Debug("CHAT_MSG_LOOT: AF.OBJECT %d (%d)", item_id, quantity)
|
MMOSimca@381
|
1601 -- Check for top level object data
|
MMOSimca@381
|
1602 local object_entry = DBEntry("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id]))
|
MMOSimca@381
|
1603 local difficulty_token = InstanceDifficultyToken()
|
MMOSimca@381
|
1604 if object_entry[difficulty_token] then
|
MMOSimca@381
|
1605 -- Increment loot count
|
MMOSimca@381
|
1606 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
|
MMOSimca@381
|
1607
|
MMOSimca@381
|
1608 -- Add drop data
|
MMOSimca@381
|
1609 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
|
MMOSimca@381
|
1610 table.insert(object_entry[difficulty_token]["opening"], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@381
|
1611 else
|
MMOSimca@381
|
1612 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
|
1613 end
|
jcallahan@179
|
1614 end,
|
jcallahan@179
|
1615 [AF.ZONE] = function(item_id, quantity)
|
MMOSimca@345
|
1616 Debug("CHAT_MSG_LOOT: AF.ZONE %d (%d)", item_id, quantity)
|
jcallahan@312
|
1617 InitializeCurrentLoot()
|
jcallahan@312
|
1618 current_loot.list[1] = ("%d:%d"):format(item_id, quantity)
|
jcallahan@179
|
1619 GenericLootUpdate("zones")
|
jcallahan@312
|
1620 current_loot = nil
|
jcallahan@179
|
1621 end,
|
jcallahan@179
|
1622 }
|
jcallahan@177
|
1623
|
jcallahan@177
|
1624
|
MMOSimca@388
|
1625 function WDP:CHAT_MSG_LOOT(event_name, message)
|
jcallahan@179
|
1626 local category
|
jcallahan@177
|
1627
|
MMOSimca@345
|
1628 local item_link, quantity = deformat(message, _G.LOOT_ITEM_PUSHED_SELF_MULTIPLE)
|
MMOSimca@345
|
1629 if not item_link then
|
MMOSimca@345
|
1630 quantity, item_link = 1, deformat(message, _G.LOOT_ITEM_PUSHED_SELF)
|
MMOSimca@345
|
1631 end
|
MMOSimca@345
|
1632 local item_id = ItemLinkToID(item_link)
|
MMOSimca@345
|
1633
|
MMOSimca@345
|
1634 if not item_id then
|
MMOSimca@345
|
1635 return
|
MMOSimca@345
|
1636 end
|
MMOSimca@345
|
1637
|
MMOSimca@345
|
1638 -- Set update category
|
MMOSimca@405
|
1639 if last_timber_spell_id and item_id == ITEM_ID_TIMBER then
|
MMOSimca@345
|
1640 category = AF.OBJECT
|
MMOSimca@345
|
1641 -- Recently changed from ~= "EXTRACT_GAS" because of some occassional bad data, and, as far as I know, no benefit.
|
MMOSimca@345
|
1642 elseif current_action.spell_label == "FISHING" then
|
jcallahan@179
|
1643 category = AF.ZONE
|
MMOSimca@388
|
1644 elseif raid_boss_id then
|
jcallahan@179
|
1645 category = AF.NPC
|
MMOSimca@347
|
1646 elseif chat_loot_timer_handle then
|
MMOSimca@347
|
1647 category = AF.ITEM
|
jcallahan@179
|
1648 end
|
MMOSimca@345
|
1649
|
MMOSimca@395
|
1650 -- We still want to record the item's data, even if it doesn't need its drop location recorded
|
MMOSimca@395
|
1651 RecordItemData(item_id, item_link, true)
|
MMOSimca@395
|
1652
|
MMOSimca@345
|
1653 -- Take action based on update category
|
jcallahan@179
|
1654 local update_func = CHAT_MSG_LOOT_UPDATE_FUNCS[category]
|
MMOSimca@412
|
1655 if not category or not update_func or BLACKLISTED_ITEMS[item_id] then
|
MMOSimca@340
|
1656 return
|
MMOSimca@340
|
1657 end
|
jcallahan@179
|
1658 update_func(item_id, quantity)
|
jcallahan@177
|
1659 end
|
MMOSimca@388
|
1660 end
|
MMOSimca@388
|
1661
|
MMOSimca@388
|
1662
|
jcallahan@97
|
1663 function WDP:RecordQuote(event_name, message, source_name, language_name)
|
jcallahan@112
|
1664 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
|
1665 return
|
jcallahan@95
|
1666 end
|
jcallahan@97
|
1667 local npc = NPCEntry(name_to_id_map[source_name])
|
jcallahan@97
|
1668 npc.quotes = npc.quotes or {}
|
jcallahan@97
|
1669 npc.quotes[event_name] = npc.quotes[event_name] or {}
|
jcallahan@97
|
1670 npc.quotes[event_name][ReplaceKeywords(message)] = true
|
jcallahan@97
|
1671 end
|
jcallahan@95
|
1672
|
jcallahan@95
|
1673
|
jcallahan@95
|
1674 do
|
jcallahan@40
|
1675 local SOBER_MATCH = _G.DRUNK_MESSAGE_ITEM_SELF1:gsub("%%s", ".+")
|
jcallahan@40
|
1676
|
jcallahan@40
|
1677 local DRUNK_COMPARES = {
|
jcallahan@40
|
1678 _G.DRUNK_MESSAGE_SELF2,
|
jcallahan@40
|
1679 _G.DRUNK_MESSAGE_SELF3,
|
jcallahan@40
|
1680 _G.DRUNK_MESSAGE_SELF4,
|
jcallahan@40
|
1681 }
|
jcallahan@40
|
1682
|
jcallahan@40
|
1683 local DRUNK_MATCHES = {
|
jcallahan@254
|
1684 (_G.DRUNK_MESSAGE_SELF2:gsub("%%s", ".+")),
|
jcallahan@254
|
1685 (_G.DRUNK_MESSAGE_SELF3:gsub("%%s", ".+")),
|
jcallahan@254
|
1686 (_G.DRUNK_MESSAGE_SELF4:gsub("%%s", ".+")),
|
jcallahan@40
|
1687 }
|
jcallahan@40
|
1688
|
jcallahan@167
|
1689 local RECIPE_MATCH = _G.ERR_LEARN_RECIPE_S:gsub("%%s", "(.*)")
|
jcallahan@167
|
1690
|
jcallahan@167
|
1691
|
jcallahan@167
|
1692 local function RecordDiscovery(tradeskill_name, tradeskill_index)
|
jcallahan@167
|
1693 if tradeskill_name == private.discovered_recipe_name then
|
catherton@479
|
1694 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
|
1695
|
jcallahan@167
|
1696 private.discovered_recipe_name = nil
|
jcallahan@167
|
1697 private.profession_level = nil
|
jcallahan@167
|
1698 private.previous_spell_id = nil
|
jcallahan@169
|
1699
|
jcallahan@169
|
1700 return true
|
jcallahan@167
|
1701 end
|
jcallahan@167
|
1702 end
|
jcallahan@167
|
1703
|
jcallahan@167
|
1704
|
jcallahan@167
|
1705 local function IterativeRecordDiscovery()
|
jcallahan@167
|
1706 TradeSkillExecutePer(RecordDiscovery)
|
jcallahan@167
|
1707 end
|
jcallahan@167
|
1708
|
jcallahan@167
|
1709
|
jcallahan@92
|
1710 function WDP:CHAT_MSG_SYSTEM(event_name, message)
|
catherton@472
|
1711 local item_link, quantity = deformat(message, ERR_QUEST_REWARD_ITEM_MULT_IS)
|
MMOSimca@400
|
1712 if not item_link then
|
catherton@472
|
1713 quantity, item_link = 1, deformat(message, ERR_QUEST_REWARD_ITEM_S)
|
MMOSimca@400
|
1714 end
|
MMOSimca@400
|
1715 local item_id = ItemLinkToID(item_link)
|
MMOSimca@400
|
1716
|
MMOSimca@400
|
1717 -- If it isn't a quest message, check the other uses of system messages
|
MMOSimca@400
|
1718 if not item_id then
|
MMOSimca@400
|
1719 if not private.trainer_shown then
|
MMOSimca@400
|
1720 local recipe_name = message:match(RECIPE_MATCH)
|
MMOSimca@400
|
1721
|
MMOSimca@400
|
1722 if recipe_name and private.previous_spell_id then
|
catherton@479
|
1723 local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
|
MMOSimca@400
|
1724
|
MMOSimca@400
|
1725 if profession_name == _G.UNKNOWN then
|
MMOSimca@400
|
1726 return
|
MMOSimca@400
|
1727 end
|
MMOSimca@400
|
1728 private.discovered_recipe_name = recipe_name
|
MMOSimca@400
|
1729 private.profession_level = prof_level
|
MMOSimca@400
|
1730
|
MMOSimca@400
|
1731 C_Timer.After(0.2, IterativeRecordDiscovery)
|
jcallahan@167
|
1732 end
|
jcallahan@167
|
1733 end
|
MMOSimca@400
|
1734
|
MMOSimca@400
|
1735 if currently_drunk then
|
MMOSimca@400
|
1736 if message == _G.DRUNK_MESSAGE_SELF1 or message:match(SOBER_MATCH) then
|
MMOSimca@400
|
1737 currently_drunk = nil
|
MMOSimca@400
|
1738 end
|
MMOSimca@400
|
1739 return
|
MMOSimca@400
|
1740 end
|
MMOSimca@400
|
1741
|
MMOSimca@400
|
1742 for index = 1, #DRUNK_MATCHES do
|
MMOSimca@400
|
1743 if message == DRUNK_COMPARES[index] or message:match(DRUNK_MATCHES[index]) then
|
MMOSimca@400
|
1744 currently_drunk = true
|
MMOSimca@400
|
1745 break
|
MMOSimca@400
|
1746 end
|
jcallahan@40
|
1747 end
|
jcallahan@40
|
1748 return
|
jcallahan@40
|
1749 end
|
jcallahan@40
|
1750
|
MMOSimca@411
|
1751 -- If it is an item, parse its link
|
MMOSimca@400
|
1752 RecordItemData(item_id, item_link, true)
|
jcallahan@40
|
1753 end
|
jcallahan@40
|
1754 end
|
jcallahan@40
|
1755
|
jcallahan@307
|
1756
|
jcallahan@331
|
1757 do
|
jcallahan@23
|
1758 local FLAGS_NPC = bit.bor(_G.COMBATLOG_OBJECT_TYPE_GUARDIAN, _G.COMBATLOG_OBJECT_CONTROL_NPC)
|
jcallahan@23
|
1759 local FLAGS_NPC_CONTROL = bit.bor(_G.COMBATLOG_OBJECT_AFFILIATION_OUTSIDER, _G.COMBATLOG_OBJECT_CONTROL_NPC)
|
jcallahan@23
|
1760
|
MMOSimca@458
|
1761 -- Spells that are cast by players/NPCs that are mistakely assigned as being cast by the target; must be blacklisted
|
MMOSimca@405
|
1762 local BLACKLISTED_SPELLS = {
|
MMOSimca@458
|
1763 [117526] = true, -- Binding Shot (cast by Hunters)
|
MMOSimca@458
|
1764 [121308] = true, -- Disguise (cast by Rogues)
|
MMOSimca@458
|
1765 [132464] = true, -- Chi Wave (cast by Monks)
|
MMOSimca@458
|
1766 [132467] = true, -- Chi Wave (cast by Monks)
|
MMOSimca@460
|
1767 [167432] = true, -- Savagery (cast by Warsong Commander)
|
MMOSimca@460
|
1768 [175077] = true, -- Fearsome Battle Standard (cast by Fearsome Battle Standard item)
|
MMOSimca@458
|
1769 [176813] = true, -- Itchy Spores (cast by Marsh Creatures in Ashran)
|
MMOSimca@458
|
1770 [183901] = true, -- Stolen Strength (cast by Felblood NPCs in Tanaan Jungle)
|
MMOSimca@458
|
1771 [183904] = true, -- Stolen Speed (cast by Felblood NPCs in Tanaan Jungle)
|
MMOSimca@458
|
1772 [183907] = true, -- Stolen Fervor (cast by Felblood NPCs in Tanaan Jungle)
|
catherton@474
|
1773 [213738] = true, -- Taste of Blood (applied by Fate and Fortune, Combat Rogue artifacts)
|
mmosimca@483
|
1774 [213877] = true, -- Vampiric Aura (used by Nathrezim Invasion bosses and transformed players)
|
catherton@474
|
1775 [215377] = true, -- The Maw Must Feed (applied by Maw of the Damned, Blood Death Knight artifact)
|
catherton@470
|
1776 [224762] = true, -- Leyline Rift (summoned by players with Leyline Mastery in Suramar)
|
catherton@474
|
1777 [225832] = true, -- Nightglow Wisp (cast by players using Wisp in a Bottle toy)
|
MMOSimca@405
|
1778 }
|
MMOSimca@405
|
1779
|
jcallahan@23
|
1780 local function RecordNPCSpell(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id, spell_name)
|
MMOSimca@405
|
1781 if not spell_id or BLACKLISTED_SPELLS[spell_id] then
|
jcallahan@23
|
1782 return
|
jcallahan@23
|
1783 end
|
jcallahan@34
|
1784 local source_type, source_id = ParseGUID(source_guid)
|
jcallahan@23
|
1785
|
jcallahan@171
|
1786 if not source_id or not UnitTypeIsNPC(source_type) then
|
jcallahan@23
|
1787 return
|
jcallahan@23
|
1788 end
|
jcallahan@23
|
1789
|
jcallahan@23
|
1790 if bit.band(FLAGS_NPC_CONTROL, source_flags) == FLAGS_NPC_CONTROL and bit.band(FLAGS_NPC, source_flags) ~= 0 then
|
jcallahan@248
|
1791 local encounter_data = NPCEntry(source_id):EncounterData(InstanceDifficultyToken())
|
jcallahan@28
|
1792 encounter_data.spells = encounter_data.spells or {}
|
jcallahan@28
|
1793 encounter_data.spells[spell_id] = (encounter_data.spells[spell_id] or 0) + 1
|
jcallahan@23
|
1794 end
|
jcallahan@23
|
1795 end
|
jcallahan@23
|
1796
|
jcallahan@115
|
1797 local HEAL_BATTLE_PETS_SPELL_ID = 125801
|
jcallahan@115
|
1798
|
jcallahan@246
|
1799 local previous_combat_event = {}
|
jcallahan@246
|
1800
|
jcallahan@23
|
1801 local COMBAT_LOG_FUNCS = {
|
jcallahan@23
|
1802 SPELL_AURA_APPLIED = RecordNPCSpell,
|
jcallahan@23
|
1803 SPELL_CAST_START = RecordNPCSpell,
|
jcallahan@115
|
1804 SPELL_CAST_SUCCESS = function(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id, spell_name)
|
jcallahan@115
|
1805 if spell_id == HEAL_BATTLE_PETS_SPELL_ID then
|
jcallahan@115
|
1806 local unit_type, unit_idnum = ParseGUID(source_guid)
|
jcallahan@115
|
1807
|
jcallahan@171
|
1808 if unit_idnum and UnitTypeIsNPC(unit_type) then
|
jcallahan@115
|
1809 NPCEntry(unit_idnum).stable_master = true
|
jcallahan@115
|
1810 end
|
jcallahan@115
|
1811 end
|
jcallahan@115
|
1812 RecordNPCSpell(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id, spell_name)
|
jcallahan@115
|
1813 end,
|
jcallahan@65
|
1814 UNIT_DIED = function(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id, spell_name)
|
jcallahan@65
|
1815 local unit_type, unit_idnum = ParseGUID(dest_guid)
|
jcallahan@65
|
1816
|
jcallahan@171
|
1817 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@245
|
1818 Debug("%s: %s is not an NPC, or has no ID.", sub_event, dest_name or _G.UNKNOWN)
|
jcallahan@177
|
1819 ClearKilledNPC()
|
jcallahan@98
|
1820 private.harvesting = nil
|
jcallahan@65
|
1821 return
|
jcallahan@65
|
1822 end
|
jcallahan@177
|
1823
|
jcallahan@246
|
1824 if source_guid == "" then
|
jcallahan@246
|
1825 source_guid = nil
|
jcallahan@246
|
1826 end
|
jcallahan@246
|
1827 local killer_guid = source_guid or previous_combat_event.source_guid
|
jcallahan@246
|
1828 local killer_name = source_name or previous_combat_event.source_name
|
jcallahan@246
|
1829
|
jcallahan@299
|
1830 if not previous_combat_event.party_damage then
|
jcallahan@312
|
1831 --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
|
1832 table.wipe(previous_combat_event)
|
jcallahan@217
|
1833 ClearKilledNPC()
|
jcallahan@306
|
1834 else
|
jcallahan@317
|
1835 --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
|
1836 end
|
jcallahan@177
|
1837 killed_npc_id = unit_idnum
|
MMOSimca@383
|
1838 C_Timer.After(0.1, ClearKilledNPC)
|
jcallahan@65
|
1839 end,
|
jcallahan@23
|
1840 }
|
jcallahan@23
|
1841
|
jcallahan@23
|
1842
|
jcallahan@246
|
1843 local NON_DAMAGE_EVENTS = {
|
jcallahan@246
|
1844 SPELL_AURA_APPLIED = true,
|
jcallahan@246
|
1845 SPELL_AURA_REMOVED = true,
|
jcallahan@246
|
1846 SPELL_AURA_REMOVED_DOSE = true,
|
jcallahan@246
|
1847 SPELL_CAST_FAILED = true,
|
jcallahan@246
|
1848 SWING_MISSED = true,
|
jcallahan@246
|
1849 }
|
jcallahan@246
|
1850
|
jcallahan@299
|
1851 local DAMAGE_EVENTS = {
|
jcallahan@299
|
1852 RANGE_DAMAGE = true,
|
jcallahan@299
|
1853 SPELL_BUILDING_DAMAGE = true,
|
jcallahan@299
|
1854 SPELL_DAMAGE = true,
|
jcallahan@299
|
1855 SPELL_PERIODIC_DAMAGE = true,
|
jcallahan@299
|
1856 SWING_DAMAGE = true,
|
jcallahan@299
|
1857 }
|
jcallahan@299
|
1858
|
jcallahan@246
|
1859
|
jcallahan@92
|
1860 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
|
1861 local combat_log_func = COMBAT_LOG_FUNCS[sub_event]
|
jcallahan@23
|
1862
|
jcallahan@23
|
1863 if not combat_log_func then
|
jcallahan@299
|
1864 if DAMAGE_EVENTS[sub_event] then
|
jcallahan@299
|
1865 table.wipe(previous_combat_event)
|
jcallahan@246
|
1866 previous_combat_event.source_name = source_name
|
jcallahan@299
|
1867
|
jcallahan@299
|
1868 if source_guid ~= dest_guid and (in_instance or group_member_guids[source_guid] or group_pet_guids[source_guid]) then
|
jcallahan@299
|
1869 previous_combat_event.party_damage = true
|
jcallahan@299
|
1870 end
|
jcallahan@246
|
1871 end
|
jcallahan@23
|
1872 return
|
jcallahan@23
|
1873 end
|
jcallahan@23
|
1874 combat_log_func(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, ...)
|
jcallahan@297
|
1875
|
jcallahan@297
|
1876 if NON_DAMAGE_EVENTS[sub_event] then
|
jcallahan@297
|
1877 table.wipe(previous_combat_event)
|
jcallahan@297
|
1878 end
|
jcallahan@23
|
1879 end
|
jcallahan@23
|
1880
|
catherton@465
|
1881
|
jcallahan@44
|
1882 local DIPLOMACY_SPELL_ID = 20599
|
jcallahan@44
|
1883 local MR_POP_RANK1_SPELL_ID = 78634
|
jcallahan@44
|
1884 local MR_POP_RANK2_SPELL_ID = 78635
|
MMOSimca@418
|
1885 local TRADING_PACT_SPELL_ID = 170200
|
jcallahan@44
|
1886
|
jcallahan@44
|
1887
|
jcallahan@92
|
1888 function WDP:COMBAT_TEXT_UPDATE(event_name, message_type, faction_name, amount)
|
jcallahan@177
|
1889 if message_type ~= "FACTION" or not killed_npc_id then
|
jcallahan@44
|
1890 return
|
jcallahan@44
|
1891 end
|
jcallahan@44
|
1892 UpdateFactionData()
|
jcallahan@44
|
1893
|
jcallahan@46
|
1894 if not faction_name or not faction_standings[faction_name] then
|
jcallahan@46
|
1895 return
|
jcallahan@46
|
1896 end
|
jcallahan@177
|
1897 local npc = NPCEntry(killed_npc_id)
|
jcallahan@177
|
1898 ClearKilledNPC()
|
jcallahan@46
|
1899
|
jcallahan@44
|
1900 if not npc then
|
jcallahan@98
|
1901 private.harvesting = nil
|
jcallahan@44
|
1902 return
|
jcallahan@44
|
1903 end
|
jcallahan@98
|
1904 npc.harvested = private.harvesting
|
jcallahan@98
|
1905 private.harvesting = nil
|
jcallahan@98
|
1906
|
jcallahan@44
|
1907 local modifier = 1
|
jcallahan@44
|
1908
|
MMOSimca@340
|
1909 -- Check for modifiers from known spells
|
jcallahan@44
|
1910 if _G.IsSpellKnown(DIPLOMACY_SPELL_ID) then
|
jcallahan@44
|
1911 modifier = modifier + 0.1
|
jcallahan@44
|
1912 end
|
jcallahan@44
|
1913 if _G.IsSpellKnown(MR_POP_RANK2_SPELL_ID) then
|
jcallahan@44
|
1914 modifier = modifier + 0.1
|
jcallahan@44
|
1915 elseif _G.IsSpellKnown(MR_POP_RANK1_SPELL_ID) then
|
jcallahan@44
|
1916 modifier = modifier + 0.05
|
jcallahan@44
|
1917 end
|
MMOSimca@418
|
1918 if _G.IsSpellKnown(TRADING_PACT_SPELL_ID) then
|
MMOSimca@418
|
1919 modifier = modifier + 0.2
|
MMOSimca@418
|
1920 end
|
jcallahan@44
|
1921
|
MMOSimca@340
|
1922 -- Determine faction ID
|
MMOSimca@340
|
1923 local faction_ID
|
MMOSimca@418
|
1924 for pseudo_faction_name, faction_data_table in pairs(private.FACTION_DATA) do
|
MMOSimca@418
|
1925 if faction_name == faction_data_table[3] then
|
MMOSimca@418
|
1926 -- Check ignore flag
|
MMOSimca@418
|
1927 if faction_data_table[2] then
|
MMOSimca@418
|
1928 return
|
MMOSimca@418
|
1929 end
|
MMOSimca@340
|
1930 faction_ID = faction_data_table[1]
|
MMOSimca@418
|
1931 break
|
MMOSimca@340
|
1932 end
|
MMOSimca@340
|
1933 end
|
MMOSimca@340
|
1934 if faction_ID and faction_ID > 0 then
|
MMOSimca@340
|
1935 -- Check for modifiers from Commendations (applied directly to the faction, account-wide)
|
MMOSimca@340
|
1936 local _, _, _, _, _, _, _, _, _, _, _, _, _, _, has_bonus_rep_gain = GetFactionInfoByID(faction_ID)
|
MMOSimca@340
|
1937 if has_bonus_rep_gain then
|
MMOSimca@340
|
1938 modifier = modifier + 1
|
MMOSimca@340
|
1939 end
|
MMOSimca@340
|
1940 end
|
MMOSimca@340
|
1941
|
MMOSimca@340
|
1942 -- Check for modifiers from buffs
|
MMOSimca@418
|
1943 for buff_name, buff_data_table in pairs(private.REP_BUFFS) do
|
jcallahan@44
|
1944 if _G.UnitBuff("player", buff_name) then
|
MMOSimca@340
|
1945 local modded_faction = buff_data_table.faction
|
jcallahan@44
|
1946
|
jcallahan@44
|
1947 if not modded_faction or faction_name == modded_faction then
|
MMOSimca@340
|
1948 if buff_data_table.ignore then
|
MMOSimca@340
|
1949 -- Some buffs from tabards convert all rep of other factions into rep for a specific faction.
|
MMOSimca@340
|
1950 -- We can't know what faction the rep was orginally from, so we must ignore the data entirely in these cases.
|
MMOSimca@340
|
1951 return
|
MMOSimca@340
|
1952 else
|
MMOSimca@340
|
1953 modifier = modifier + buff_data_table.modifier
|
MMOSimca@340
|
1954 end
|
jcallahan@44
|
1955 end
|
jcallahan@44
|
1956 end
|
jcallahan@44
|
1957 end
|
catherton@465
|
1958
|
jcallahan@65
|
1959 npc.reputations = npc.reputations or {}
|
jcallahan@65
|
1960 npc.reputations[("%s:%s"):format(faction_name, faction_standings[faction_name])] = math.floor(amount / modifier)
|
jcallahan@32
|
1961 end
|
jcallahan@44
|
1962 end -- do-block
|
jcallahan@18
|
1963
|
jcallahan@18
|
1964
|
jcallahan@140
|
1965 function WDP:CURSOR_UPDATE(event_name)
|
MMOSimca@355
|
1966 if current_action.fishing_target or _G.Minimap:IsMouseOver() then
|
jcallahan@140
|
1967 return
|
jcallahan@140
|
1968 end
|
jcallahan@140
|
1969 local text = _G["GameTooltipTextLeft1"]:GetText()
|
jcallahan@140
|
1970
|
MMOSimca@355
|
1971 -- Handle Fishing
|
MMOSimca@355
|
1972 if (current_action.spell_label == "FISHING") then
|
MMOSimca@355
|
1973 if not text or text == "Fishing Bobber" then
|
MMOSimca@355
|
1974 text = "NONE"
|
MMOSimca@355
|
1975 else
|
MMOSimca@355
|
1976 current_action.fishing_target = true
|
MMOSimca@355
|
1977 end
|
MMOSimca@355
|
1978 current_action.identifier = ("%s:%s"):format(current_action.spell_label, text)
|
MMOSimca@355
|
1979 -- Handle Garrison Cache
|
MMOSimca@355
|
1980 elseif private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text] then
|
MMOSimca@355
|
1981 last_garrison_cache_object_id = private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text]
|
jcallahan@140
|
1982 end
|
jcallahan@140
|
1983 end
|
jcallahan@140
|
1984
|
jcallahan@140
|
1985
|
jcallahan@92
|
1986 function WDP:ITEM_TEXT_BEGIN(event_name)
|
jcallahan@42
|
1987 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@42
|
1988
|
jcallahan@42
|
1989 if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT or _G.UnitName("npc") ~= _G.ItemTextGetItem() then
|
jcallahan@42
|
1990 return
|
jcallahan@42
|
1991 end
|
jcallahan@42
|
1992 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@42
|
1993 end
|
jcallahan@42
|
1994
|
jcallahan@42
|
1995
|
jcallahan@13
|
1996 do
|
MMOSimca@343
|
1997 local LOOT_OPENED_VERIFY_FUNCS = {
|
jcallahan@324
|
1998 -- 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
|
1999 [AF.ITEM] = function()
|
jcallahan@16
|
2000 local locked_item_id
|
jcallahan@16
|
2001
|
jcallahan@16
|
2002 for bag_index = 0, _G.NUM_BAG_FRAMES do
|
jcallahan@16
|
2003 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do
|
jcallahan@324
|
2004 local _, _, is_locked, _, _, is_lootable = _G.GetContainerItemInfo(bag_index, slot_index)
|
jcallahan@324
|
2005
|
jcallahan@324
|
2006 if is_locked and is_lootable then
|
jcallahan@16
|
2007 locked_item_id = ItemLinkToID(_G.GetContainerItemLink(bag_index, slot_index))
|
jcallahan@165
|
2008 break
|
jcallahan@16
|
2009 end
|
jcallahan@16
|
2010 end
|
jcallahan@165
|
2011
|
jcallahan@165
|
2012 if locked_item_id then
|
jcallahan@165
|
2013 break
|
jcallahan@165
|
2014 end
|
jcallahan@16
|
2015 end
|
jcallahan@16
|
2016
|
MMOSimca@367
|
2017 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
|
2018 return false
|
jcallahan@16
|
2019 end
|
jcallahan@122
|
2020 current_action.identifier = locked_item_id
|
jcallahan@16
|
2021 return true
|
jcallahan@16
|
2022 end,
|
MMOSimca@401
|
2023 [AF.NPC] = function()
|
MMOSimca@401
|
2024 return not _G.IsFishingLoot()
|
MMOSimca@401
|
2025 end,
|
MMOSimca@401
|
2026 [AF.OBJECT] = function()
|
MMOSimca@401
|
2027 return not _G.IsFishingLoot()
|
MMOSimca@401
|
2028 end,
|
jcallahan@17
|
2029 [AF.ZONE] = function()
|
jcallahan@140
|
2030 current_action.zone_data = UpdateDBEntryLocation("zones", current_action.identifier)
|
jcallahan@210
|
2031 return _G.IsFishingLoot()
|
jcallahan@17
|
2032 end,
|
jcallahan@13
|
2033 }
|
jcallahan@13
|
2034
|
jcallahan@13
|
2035
|
MMOSimca@343
|
2036 local LOOT_OPENED_UPDATE_FUNCS = {
|
jcallahan@16
|
2037 [AF.ITEM] = function()
|
jcallahan@28
|
2038 GenericLootUpdate("items")
|
jcallahan@28
|
2039 end,
|
jcallahan@28
|
2040 [AF.NPC] = function()
|
jcallahan@75
|
2041 local difficulty_token = InstanceDifficultyToken()
|
jcallahan@312
|
2042 local loot_label = current_loot.label
|
jcallahan@77
|
2043 local source_list = {}
|
jcallahan@75
|
2044
|
jcallahan@131
|
2045 for source_guid, loot_data in pairs(current_loot.sources) do
|
jcallahan@331
|
2046 local _, source_id = ParseGUID(source_guid)
|
jcallahan@75
|
2047 local npc = NPCEntry(source_id)
|
jcallahan@75
|
2048
|
jcallahan@75
|
2049 if npc then
|
jcallahan@248
|
2050 local encounter_data = npc:EncounterData(difficulty_token)
|
jcallahan@312
|
2051 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
jcallahan@75
|
2052
|
jcallahan@78
|
2053 if not source_list[source_guid] then
|
jcallahan@77
|
2054 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@426
|
2055 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
jcallahan@312
|
2056 source_list[source_guid] = true
|
jcallahan@77
|
2057 end
|
jcallahan@77
|
2058
|
jcallahan@309
|
2059 for loot_token, quantity in pairs(loot_data) do
|
jcallahan@312
|
2060 local loot_type, currency_texture = (":"):split(loot_token)
|
jcallahan@312
|
2061
|
jcallahan@312
|
2062 if loot_type == "currency" and currency_texture then
|
jcallahan@312
|
2063 table.insert(encounter_data[loot_label], ("currency:%d:%s"):format(quantity, currency_texture))
|
jcallahan@309
|
2064 elseif loot_token == "money" then
|
jcallahan@312
|
2065 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
jcallahan@309
|
2066 else
|
jcallahan@312
|
2067 table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
|
jcallahan@309
|
2068 end
|
jcallahan@75
|
2069 end
|
jcallahan@75
|
2070 end
|
jcallahan@75
|
2071 end
|
jcallahan@16
|
2072 end,
|
jcallahan@13
|
2073 [AF.OBJECT] = function()
|
jcallahan@28
|
2074 GenericLootUpdate("objects", InstanceDifficultyToken())
|
jcallahan@17
|
2075 end,
|
jcallahan@17
|
2076 [AF.ZONE] = function()
|
MMOSimca@328
|
2077 if not (current_loot.map_level and current_loot.x and current_loot.y and current_loot.zone_data) then
|
MMOSimca@328
|
2078 return
|
MMOSimca@328
|
2079 end
|
jcallahan@141
|
2080 local location_token = ("%d:%d:%d"):format(current_loot.map_level, current_loot.x, current_loot.y)
|
jcallahan@41
|
2081
|
jcallahan@41
|
2082 -- This will start life as a boolean true.
|
jcallahan@131
|
2083 if _G.type(current_loot.zone_data[location_token]) ~= "table" then
|
jcallahan@131
|
2084 current_loot.zone_data[location_token] = {
|
jcallahan@41
|
2085 drops = {}
|
jcallahan@41
|
2086 }
|
jcallahan@41
|
2087 end
|
jcallahan@132
|
2088 local loot_count = ("%s_count"):format(current_loot.label)
|
jcallahan@131
|
2089 current_loot.zone_data[location_token][loot_count] = (current_loot.zone_data[location_token][loot_count] or 0) + 1
|
jcallahan@41
|
2090
|
jcallahan@131
|
2091 if current_loot.sources then
|
jcallahan@131
|
2092 for source_guid, loot_data in pairs(current_loot.sources) do
|
jcallahan@131
|
2093 for item_id, quantity in pairs(loot_data) do
|
jcallahan@131
|
2094 table.insert(current_loot.zone_data[location_token].drops, ("%d:%d"):format(item_id, quantity))
|
jcallahan@131
|
2095 end
|
jcallahan@131
|
2096 end
|
jcallahan@131
|
2097 end
|
jcallahan@131
|
2098
|
jcallahan@131
|
2099 if #current_loot.list <= 0 then
|
jcallahan@131
|
2100 return
|
jcallahan@131
|
2101 end
|
jcallahan@131
|
2102
|
jcallahan@131
|
2103 for index = 1, #current_loot.list do
|
MMOSimca@443
|
2104 table.insert(current_loot.zone_data[location_token].drops, current_loot.list[index])
|
jcallahan@41
|
2105 end
|
jcallahan@13
|
2106 end,
|
jcallahan@13
|
2107 }
|
jcallahan@13
|
2108
|
jcallahan@79
|
2109 -- Prevent opening the same loot window multiple times from recording data multiple times.
|
jcallahan@79
|
2110 local loot_guid_registry = {}
|
jcallahan@124
|
2111
|
jcallahan@124
|
2112
|
jcallahan@124
|
2113 function WDP:LOOT_CLOSED(event_name)
|
MMOSimca@398
|
2114 ClearChatLootData()
|
jcallahan@131
|
2115 current_loot = nil
|
jcallahan@131
|
2116 table.wipe(current_action)
|
jcallahan@124
|
2117 end
|
jcallahan@124
|
2118
|
jcallahan@13
|
2119
|
jcallahan@322
|
2120 local function ExtrapolatedCurrentActionFromLootData(event_name)
|
MMOSimca@402
|
2121 local log_source = event_name .. "- ExtrapolatedCurrentActionFromLootData"
|
MMOSimca@402
|
2122 local previous_spell_label = current_action.spell_label
|
jcallahan@322
|
2123 local extrapolated_guid_registry = {}
|
jcallahan@322
|
2124 local num_guids = 0
|
MMOSimca@402
|
2125 table.wipe(current_action)
|
MMOSimca@402
|
2126
|
MMOSimca@402
|
2127 if _G.IsFishingLoot() then
|
MMOSimca@402
|
2128 -- Set up a proper 'fishing' current_action table
|
MMOSimca@402
|
2129 local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
|
MMOSimca@402
|
2130 if not (zone_name and area_id and x and y and map_level) then
|
catherton@468
|
2131 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
|
2132 return
|
MMOSimca@402
|
2133 end
|
MMOSimca@402
|
2134 current_action.instance_token = instance_token
|
MMOSimca@402
|
2135 current_action.map_level = map_level
|
MMOSimca@402
|
2136 current_action.x = x
|
MMOSimca@402
|
2137 current_action.y = y
|
MMOSimca@402
|
2138 current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
|
MMOSimca@402
|
2139 current_action.spell_label = "FISHING"
|
MMOSimca@402
|
2140 current_action.loot_label = "fishing"
|
MMOSimca@402
|
2141 current_action.identifier = "FISHING:NONE"
|
MMOSimca@402
|
2142 current_action.target_type = AF.ZONE
|
MMOSimca@402
|
2143
|
MMOSimca@402
|
2144 Debug("%s: Fishing loot detected.", log_source)
|
MMOSimca@402
|
2145 return true
|
MMOSimca@402
|
2146 end
|
jcallahan@322
|
2147
|
MMOSimca@344
|
2148 -- Loot extrapolation cannot handle objects that need special spell labels (like HERBALISM or MINING) (MIND_CONTROL is okay)
|
MMOSimca@402
|
2149 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
|
2150 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
|
2151 return false
|
MMOSimca@344
|
2152 end
|
MMOSimca@344
|
2153
|
jcallahan@322
|
2154 for loot_slot = 1, _G.GetNumLootItems() do
|
jcallahan@322
|
2155 local loot_info = {
|
jcallahan@322
|
2156 _G.GetLootSourceInfo(loot_slot)
|
jcallahan@322
|
2157 }
|
jcallahan@322
|
2158
|
jcallahan@322
|
2159 for loot_index = 1, #loot_info, 2 do
|
jcallahan@322
|
2160 local source_guid = loot_info[loot_index]
|
jcallahan@322
|
2161
|
jcallahan@322
|
2162 if not extrapolated_guid_registry[source_guid] then
|
jcallahan@322
|
2163 local unit_type, unit_idnum = ParseGUID(source_guid)
|
jcallahan@322
|
2164
|
jcallahan@322
|
2165 if unit_type and unit_idnum then
|
jcallahan@322
|
2166 extrapolated_guid_registry[source_guid] = {
|
jcallahan@322
|
2167 unit_type,
|
jcallahan@322
|
2168 unit_idnum
|
jcallahan@322
|
2169 }
|
jcallahan@322
|
2170
|
jcallahan@322
|
2171 num_guids = num_guids + 1
|
jcallahan@322
|
2172 end
|
jcallahan@322
|
2173 end
|
jcallahan@322
|
2174 end
|
jcallahan@322
|
2175 end
|
jcallahan@322
|
2176
|
jcallahan@322
|
2177 if num_guids == 0 then
|
jcallahan@322
|
2178 Debug("%s: No GUIDs found in loot. Blank loot window?", log_source)
|
jcallahan@322
|
2179 return false
|
jcallahan@322
|
2180 end
|
jcallahan@326
|
2181
|
jcallahan@322
|
2182 local num_npcs = 0
|
jcallahan@322
|
2183 local num_objects = 0
|
jcallahan@324
|
2184 local num_itemcontainers = 0
|
jcallahan@322
|
2185
|
jcallahan@322
|
2186 for source_guid, guid_data in pairs(extrapolated_guid_registry) do
|
jcallahan@322
|
2187 local unit_type = guid_data[1]
|
jcallahan@324
|
2188 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
|
2189
|
jcallahan@322
|
2190 if loot_label then
|
jcallahan@322
|
2191 local unit_idnum = guid_data[2]
|
jcallahan@322
|
2192
|
jcallahan@322
|
2193 if loot_guid_registry[loot_label] and loot_guid_registry[loot_label][source_guid] then
|
jcallahan@322
|
2194 Debug("%s: Previously scanned loot for unit with GUID %s and identifier %s.", log_source, source_guid, unit_idnum)
|
jcallahan@322
|
2195 elseif unit_type == private.UNIT_TYPES.OBJECT and unit_idnum ~= OBJECT_ID_FISHING_BOBBER then
|
jcallahan@322
|
2196 current_action.loot_label = loot_label
|
jcallahan@322
|
2197 current_action.spell_label = "OPENING"
|
jcallahan@322
|
2198 current_action.target_type = AF.OBJECT
|
jcallahan@322
|
2199 current_action.identifier = unit_idnum
|
jcallahan@322
|
2200 num_objects = num_objects + 1
|
jcallahan@322
|
2201 elseif UnitTypeIsNPC(unit_type) then
|
jcallahan@322
|
2202 current_action.loot_label = loot_label
|
jcallahan@322
|
2203 current_action.target_type = AF.NPC
|
jcallahan@322
|
2204 current_action.identifier = unit_idnum
|
jcallahan@322
|
2205 num_npcs = num_npcs + 1
|
jcallahan@324
|
2206 elseif unit_type == private.UNIT_TYPES.PLAYER then
|
jcallahan@331
|
2207 -- Item container GUIDs are currently of the 'PLAYER' type; this may be unintended and could change in the future.
|
jcallahan@324
|
2208 current_action.loot_label = loot_label
|
jcallahan@324
|
2209 current_action.target_type = AF.ITEM
|
jcallahan@324
|
2210 -- current_action.identifier assigned during loot verification.
|
jcallahan@324
|
2211 num_itemcontainers = num_itemcontainers + 1
|
jcallahan@322
|
2212 end
|
jcallahan@322
|
2213 else
|
jcallahan@322
|
2214 -- 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
|
2215 Debug("%s: Unit with GUID %s has unsupported type for looting.", log_source, source_guid)
|
jcallahan@322
|
2216 return false
|
jcallahan@322
|
2217 end
|
jcallahan@322
|
2218 end
|
jcallahan@322
|
2219
|
jcallahan@322
|
2220 if not current_action.target_type then
|
jcallahan@322
|
2221 Debug("%s: Failure to obtain target_type.", log_source)
|
jcallahan@322
|
2222 return false
|
jcallahan@322
|
2223 end
|
jcallahan@322
|
2224
|
jcallahan@322
|
2225 -- 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
|
2226 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
|
2227 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
|
2228 return false
|
jcallahan@322
|
2229 end
|
jcallahan@322
|
2230
|
jcallahan@322
|
2231 return true
|
jcallahan@322
|
2232 end
|
jcallahan@322
|
2233
|
jcallahan@322
|
2234
|
MMOSimca@343
|
2235 function WDP:LOOT_OPENED(event_name)
|
MMOSimca@398
|
2236 ClearChatLootData()
|
MMOSimca@387
|
2237
|
jcallahan@132
|
2238 if current_loot then
|
jcallahan@322
|
2239 current_loot = nil
|
jcallahan@322
|
2240 Debug("%s: Previous loot did not process in time for this event. Attempting to extrapolate current_action from loot data.", event_name)
|
jcallahan@322
|
2241
|
jcallahan@322
|
2242 if not ExtrapolatedCurrentActionFromLootData(event_name) then
|
jcallahan@322
|
2243 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
|
jcallahan@322
|
2244 return
|
jcallahan@322
|
2245 end
|
jcallahan@18
|
2246 end
|
jcallahan@151
|
2247
|
jcallahan@151
|
2248 if not current_action.target_type then
|
jcallahan@322
|
2249 if not ExtrapolatedCurrentActionFromLootData(event_name) then
|
jcallahan@322
|
2250 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
|
jcallahan@322
|
2251 return
|
jcallahan@322
|
2252 end
|
jcallahan@151
|
2253 end
|
MMOSimca@343
|
2254 local verify_func = LOOT_OPENED_VERIFY_FUNCS[current_action.target_type]
|
MMOSimca@343
|
2255 local update_func = LOOT_OPENED_UPDATE_FUNCS[current_action.target_type]
|
jcallahan@13
|
2256
|
jcallahan@14
|
2257 if not verify_func or not update_func then
|
jcallahan@322
|
2258 Debug("%s: The current action's target type is unsupported or nil.", event_name)
|
jcallahan@13
|
2259 return
|
jcallahan@13
|
2260 end
|
jcallahan@13
|
2261
|
jcallahan@14
|
2262 if _G.type(verify_func) == "function" and not verify_func() then
|
jcallahan@324
|
2263 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
|
2264 return
|
jcallahan@14
|
2265 end
|
jcallahan@80
|
2266 local guids_used = {}
|
jcallahan@132
|
2267
|
jcallahan@301
|
2268 InitializeCurrentLoot()
|
jcallahan@217
|
2269 loot_guid_registry[current_loot.label] = loot_guid_registry[current_loot.label] or {}
|
jcallahan@217
|
2270
|
jcallahan@55
|
2271 for loot_slot = 1, _G.GetNumLootItems() do
|
catherton@463
|
2272 local texturefiledataID, item_text, slot_quantity, quality, locked = _G.GetLootSlotInfo(loot_slot)
|
jcallahan@55
|
2273 local slot_type = _G.GetLootSlotType(loot_slot)
|
catherton@463
|
2274 local loot_info = { _G.GetLootSourceInfo(loot_slot) }
|
catherton@464
|
2275 local loot_link = _G.GetLootSlotLink(loot_slot)
|
jcallahan@13
|
2276
|
jcallahan@237
|
2277 -- Odd index is GUID, even is count.
|
jcallahan@237
|
2278 for loot_index = 1, #loot_info, 2 do
|
jcallahan@237
|
2279 local source_guid = loot_info[loot_index]
|
jcallahan@75
|
2280
|
jcallahan@237
|
2281 if not loot_guid_registry[current_loot.label][source_guid] then
|
jcallahan@237
|
2282 local loot_quantity = loot_info[loot_index + 1]
|
jcallahan@324
|
2283 -- There is a new bug in 5.4.0 that causes GetLootSlotInfo() to (rarely) return nil values for slot_quantity.
|
jcallahan@324
|
2284 if slot_quantity then
|
jcallahan@324
|
2285 -- 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
|
2286 if slot_quantity > loot_quantity then
|
jcallahan@324
|
2287 loot_quantity = slot_quantity
|
jcallahan@324
|
2288 end
|
jcallahan@324
|
2289 local source_type, source_id = ParseGUID(source_guid)
|
MMOSimca@329
|
2290 local source_key = ("%s:%d"):format(source_type, source_id)
|
jcallahan@324
|
2291
|
MMOSimca@366
|
2292 if slot_type == LOOT_SLOT_ITEM then
|
catherton@464
|
2293 if loot_link then
|
catherton@464
|
2294 local item_id = ItemLinkToID(loot_link)
|
catherton@464
|
2295 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
|
2296 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
catherton@464
|
2297 current_loot.sources[source_guid][item_id] = (current_loot.sources[source_guid][item_id] or 0) + loot_quantity
|
catherton@464
|
2298 guids_used[source_guid] = true
|
catherton@463
|
2299 else
|
catherton@463
|
2300 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
|
2301 end
|
MMOSimca@366
|
2302 elseif slot_type == LOOT_SLOT_MONEY then
|
jcallahan@324
|
2303 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
|
2304 if current_loot.target_type == AF.ZONE then
|
jcallahan@324
|
2305 table.insert(current_loot.list, ("money:%d"):format(loot_quantity))
|
jcallahan@324
|
2306 else
|
jcallahan@324
|
2307 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
MMOSimca@367
|
2308 current_loot.sources[source_guid]["money"] = (current_loot.sources[source_guid]["money"] or 0) + loot_quantity
|
jcallahan@324
|
2309 guids_used[source_guid] = true
|
jcallahan@324
|
2310 end
|
MMOSimca@366
|
2311 elseif slot_type == LOOT_SLOT_CURRENCY then
|
jcallahan@324
|
2312 -- Same bug with GetLootSlotInfo() will screw up currency when it happens, so we won't process this slot's loot.
|
catherton@463
|
2313 if loot_link then
|
catherton@464
|
2314 local icon_texture = CurrencyLinkToTexture(loot_link)
|
jcallahan@324
|
2315 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
|
2316 if current_loot.target_type == AF.ZONE then
|
catherton@463
|
2317 table.insert(current_loot.list, ("currency:%d:%s"):format(loot_quantity, icon_texture))
|
jcallahan@324
|
2318 else
|
catherton@463
|
2319 local currency_token = ("currency:%s"):format(icon_texture)
|
jcallahan@324
|
2320
|
jcallahan@324
|
2321 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
|
MMOSimca@367
|
2322 current_loot.sources[source_guid][currency_token] = (current_loot.sources[source_guid][currency_token] or 0) + loot_quantity
|
jcallahan@324
|
2323 guids_used[source_guid] = true
|
jcallahan@324
|
2324 end
|
jcallahan@324
|
2325 else
|
catherton@463
|
2326 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
|
2327 end
|
jcallahan@308
|
2328 end
|
jcallahan@324
|
2329 else
|
jcallahan@324
|
2330 -- 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
|
2331 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
|
2332 end
|
jcallahan@75
|
2333 end
|
jcallahan@13
|
2334 end
|
jcallahan@13
|
2335 end
|
jcallahan@80
|
2336
|
jcallahan@81
|
2337 for guid in pairs(guids_used) do
|
jcallahan@217
|
2338 loot_guid_registry[current_loot.label][guid] = true
|
jcallahan@80
|
2339 end
|
jcallahan@13
|
2340 update_func()
|
jcallahan@1
|
2341 end
|
jcallahan@13
|
2342 end -- do-block
|
jcallahan@0
|
2343
|
jcallahan@0
|
2344
|
jcallahan@89
|
2345 function WDP:MAIL_SHOW(event_name)
|
MMOSimca@436
|
2346 WDP:StopChatLootRecording(event_name)
|
jcallahan@89
|
2347 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@89
|
2348
|
jcallahan@89
|
2349 if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT then
|
jcallahan@89
|
2350 return
|
jcallahan@89
|
2351 end
|
jcallahan@89
|
2352 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@89
|
2353 end
|
jcallahan@89
|
2354
|
jcallahan@89
|
2355
|
jcallahan@44
|
2356 do
|
jcallahan@44
|
2357 local POINT_MATCH_PATTERNS = {
|
jcallahan@44
|
2358 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2359 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2360 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_5V5:gsub("%%d", "(%%d+)")), -- May no longer be necessary
|
jcallahan@44
|
2361 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_BG:gsub("%%d", "(%%d+)")),
|
jcallahan@44
|
2362 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3_BG:gsub("%%d", "(%%d+)")),
|
jcallahan@44
|
2363 }
|
jcallahan@5
|
2364
|
jcallahan@68
|
2365 local ITEM_REQ_REPUTATION_MATCH = "Requires (.-) %- (.*)"
|
jcallahan@87
|
2366 local ITEM_REQ_QUEST_MATCH1 = "Requires: .*"
|
jcallahan@87
|
2367 local ITEM_REQ_QUEST_MATCH2 = "Must have completed: .*"
|
jcallahan@68
|
2368
|
jcallahan@133
|
2369 local current_merchant
|
jcallahan@133
|
2370 local merchant_standing
|
jcallahan@133
|
2371
|
jcallahan@133
|
2372 function WDP:MERCHANT_CLOSED(event_name)
|
MMOSimca@436
|
2373 WDP:ResumeChatLootRecording(event_name)
|
jcallahan@133
|
2374 current_merchant = nil
|
jcallahan@133
|
2375 merchant_standing = nil
|
jcallahan@133
|
2376 end
|
jcallahan@133
|
2377
|
jcallahan@133
|
2378
|
jcallahan@89
|
2379 function WDP:UpdateMerchantItems(event_name)
|
jcallahan@144
|
2380 if not current_merchant or event_name == "MERCHANT_SHOW" then
|
MMOSimca@436
|
2381 WDP:StopChatLootRecording(event_name)
|
jcallahan@195
|
2382 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@4
|
2383
|
jcallahan@171
|
2384 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@133
|
2385 return
|
jcallahan@133
|
2386 end
|
jcallahan@331
|
2387 local _, faction_standing = UnitFactionStanding("npc")
|
jcallahan@331
|
2388 merchant_standing = faction_standing
|
jcallahan@133
|
2389 current_merchant = NPCEntry(unit_idnum)
|
jcallahan@133
|
2390 current_merchant.sells = current_merchant.sells or {}
|
jcallahan@44
|
2391 end
|
jcallahan@55
|
2392 local current_filters = _G.GetMerchantFilter()
|
jcallahan@57
|
2393 _G.SetMerchantFilter(_G.LE_LOOT_FILTER_ALL)
|
jcallahan@57
|
2394 _G.MerchantFrame_Update()
|
jcallahan@57
|
2395
|
jcallahan@150
|
2396 local num_items = _G.GetMerchantNumItems()
|
jcallahan@150
|
2397
|
jcallahan@44
|
2398 for item_index = 1, num_items do
|
jcallahan@44
|
2399 local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.GetMerchantItemInfo(item_index)
|
jcallahan@44
|
2400 local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index))
|
jcallahan@5
|
2401
|
jcallahan@324
|
2402 DatamineTT:ClearLines()
|
jcallahan@324
|
2403 DatamineTT:SetMerchantItem(item_index)
|
jcallahan@324
|
2404
|
jcallahan@324
|
2405 if not item_id then
|
jcallahan@324
|
2406 local item_name, item_link = DatamineTT:GetItem()
|
jcallahan@324
|
2407 item_id = ItemLinkToID(item_link)
|
MMOSimca@354
|
2408 -- GetMerchantItemLink() still ocassionally fails as of Patch 6.0.2. It fails so badly that debug functions cause considerable slowdown.
|
jcallahan@324
|
2409 end
|
jcallahan@324
|
2410
|
jcallahan@44
|
2411 if item_id and item_id > 0 then
|
jcallahan@44
|
2412 local price_string = ActualCopperCost(copper_price, merchant_standing)
|
jcallahan@5
|
2413
|
jcallahan@68
|
2414 local num_lines = DatamineTT:NumLines()
|
jcallahan@68
|
2415
|
jcallahan@68
|
2416 for line_index = 1, num_lines do
|
jcallahan@68
|
2417 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@68
|
2418
|
jcallahan@68
|
2419 if not current_line then
|
jcallahan@68
|
2420 break
|
jcallahan@68
|
2421 end
|
jcallahan@68
|
2422 local faction, reputation = current_line:GetText():match(ITEM_REQ_REPUTATION_MATCH)
|
jcallahan@68
|
2423
|
jcallahan@68
|
2424 if faction or reputation then
|
jcallahan@68
|
2425 DBEntry("items", item_id).req_reputation = ("%s:%s"):format(faction:gsub("-", ""), reputation:upper())
|
jcallahan@68
|
2426 break
|
jcallahan@68
|
2427 end
|
jcallahan@68
|
2428 end
|
jcallahan@68
|
2429
|
jcallahan@87
|
2430 for line_index = 1, num_lines do
|
jcallahan@87
|
2431 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@87
|
2432
|
jcallahan@87
|
2433 if not current_line then
|
jcallahan@87
|
2434 break
|
jcallahan@87
|
2435 end
|
jcallahan@87
|
2436 local line_text = current_line:GetText()
|
jcallahan@87
|
2437 local quest_name = line_text:match(ITEM_REQ_QUEST_MATCH1) or line_text:match(ITEM_REQ_QUEST_MATCH2)
|
jcallahan@87
|
2438
|
jcallahan@87
|
2439 if quest_name then
|
jcallahan@87
|
2440 DBEntry("items", item_id).req_quest = ("%s"):format(quest_name:gsub("(.+): ", ""), quest_name)
|
jcallahan@87
|
2441 break
|
jcallahan@87
|
2442 end
|
jcallahan@87
|
2443 end
|
jcallahan@87
|
2444
|
jcallahan@44
|
2445 if extended_cost then
|
jcallahan@53
|
2446 local battleground_rating = 0
|
jcallahan@53
|
2447 local personal_rating = 0
|
jcallahan@53
|
2448 local required_season_amount
|
jcallahan@5
|
2449
|
jcallahan@68
|
2450 for line_index = 1, num_lines do
|
jcallahan@44
|
2451 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
|
jcallahan@5
|
2452
|
jcallahan@44
|
2453 if not current_line then
|
jcallahan@44
|
2454 break
|
jcallahan@44
|
2455 end
|
jcallahan@53
|
2456 required_season_amount = current_line:GetText():match("Requires earning a total of (%d+)\n(.-) for the season.")
|
jcallahan@5
|
2457
|
jcallahan@44
|
2458 for match_index = 1, #POINT_MATCH_PATTERNS do
|
jcallahan@44
|
2459 local match1, match2 = current_line:GetText():match(POINT_MATCH_PATTERNS[match_index])
|
jcallahan@53
|
2460 personal_rating = personal_rating + (match1 or 0)
|
jcallahan@53
|
2461 battleground_rating = battleground_rating + (match2 or 0)
|
jcallahan@5
|
2462
|
jcallahan@44
|
2463 if match1 or match2 then
|
jcallahan@44
|
2464 break
|
jcallahan@44
|
2465 end
|
jcallahan@44
|
2466 end
|
jcallahan@5
|
2467 end
|
jcallahan@44
|
2468 local currency_list = {}
|
jcallahan@44
|
2469 local item_count = _G.GetMerchantItemCostInfo(item_index)
|
jcallahan@50
|
2470
|
jcallahan@50
|
2471 -- Keeping this around in case Blizzard makes the two points diverge at some point.
|
jcallahan@53
|
2472 -- price_string = ("%s:%s:%s:%s"):format(price_string, battleground_rating, personal_rating, required_season_amount or 0)
|
jcallahan@53
|
2473 price_string = ("%s:%s:%s"):format(price_string, personal_rating, required_season_amount or 0)
|
jcallahan@5
|
2474
|
jcallahan@44
|
2475 for cost_index = 1, item_count do
|
jcallahan@324
|
2476 -- The third return (Blizz calls "currency_link") of GetMerchantItemCostItem only returns item links as of Patch 5.3.0.
|
jcallahan@317
|
2477 local icon_texture, amount_required, item_link = _G.GetMerchantItemCostItem(item_index, cost_index)
|
jcallahan@317
|
2478 local currency_identifier = item_link and ItemLinkToID(item_link) or nil
|
jcallahan@317
|
2479
|
jcallahan@317
|
2480 if (not currency_identifier or currency_identifier < 1) and icon_texture then
|
jcallahan@317
|
2481 currency_identifier = icon_texture:match("[^\\]+$"):lower()
|
jcallahan@317
|
2482 end
|
jcallahan@317
|
2483
|
jcallahan@317
|
2484 if currency_identifier then
|
jcallahan@317
|
2485 currency_list[#currency_list + 1] = ("(%s:%s)"):format(amount_required, currency_identifier)
|
jcallahan@44
|
2486 end
|
jcallahan@44
|
2487 end
|
jcallahan@44
|
2488
|
jcallahan@44
|
2489 for currency_index = 1, #currency_list do
|
jcallahan@44
|
2490 price_string = ("%s:%s"):format(price_string, currency_list[currency_index])
|
jcallahan@5
|
2491 end
|
jcallahan@5
|
2492 end
|
jcallahan@133
|
2493 current_merchant.sells[item_id] = ("%s:%s:[%s]"):format(num_available, stack_size, price_string)
|
jcallahan@44
|
2494 end
|
jcallahan@44
|
2495 end
|
jcallahan@5
|
2496
|
jcallahan@44
|
2497 if _G.CanMerchantRepair() then
|
jcallahan@133
|
2498 current_merchant.can_repair = true
|
jcallahan@5
|
2499 end
|
jcallahan@57
|
2500 _G.SetMerchantFilter(current_filters)
|
jcallahan@57
|
2501 _G.MerchantFrame_Update()
|
jcallahan@4
|
2502 end
|
jcallahan@44
|
2503 end -- do-block
|
jcallahan@4
|
2504
|
jcallahan@89
|
2505
|
jcallahan@92
|
2506 function WDP:PET_BAR_UPDATE(event_name)
|
MMOSimca@336
|
2507 if not private.NON_LOOT_SPELL_LABELS[current_action.spell_label] then
|
jcallahan@25
|
2508 return
|
jcallahan@25
|
2509 end
|
jcallahan@34
|
2510 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("pet"))
|
jcallahan@25
|
2511
|
jcallahan@171
|
2512 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
|
jcallahan@25
|
2513 return
|
jcallahan@25
|
2514 end
|
jcallahan@29
|
2515 NPCEntry(unit_idnum).mind_control = true
|
jcallahan@122
|
2516 table.wipe(current_action)
|
jcallahan@25
|
2517 end
|
jcallahan@25
|
2518
|
jcallahan@25
|
2519
|
MMOSimca@368
|
2520 -- This function produces data currently unused by wowdb.com, and it causes unneeded bloat in the raw lua DB.
|
MMOSimca@442
|
2521 --[[local LPJ = LibStub("LibPetJournal-2.0")
|
MMOSimca@442
|
2522 function WDP:PET_JOURNAL_LIST_UPDATE(event_name)
|
MMOSimca@346
|
2523 if DEBUGGING then
|
jcallahan@309
|
2524 return
|
jcallahan@309
|
2525 end
|
jcallahan@309
|
2526
|
jcallahan@115
|
2527 local num_pets = LPJ:NumPets()
|
jcallahan@115
|
2528
|
jcallahan@115
|
2529 for index, pet_id in LPJ:IteratePetIDs() do
|
jcallahan@115
|
2530 local _, _, is_owned, _, level, _, _, name, icon, pet_type, npc_id, _, _, is_wild = _G.C_PetJournal.GetPetInfoByIndex(index)
|
jcallahan@115
|
2531
|
jcallahan@115
|
2532 if is_owned then
|
jcallahan@115
|
2533 local health, max_health, attack, speed, rarity = _G.C_PetJournal.GetPetStats(pet_id)
|
jcallahan@115
|
2534
|
jcallahan@139
|
2535 if rarity then
|
jcallahan@139
|
2536 local rarity_name = _G["BATTLE_PET_BREED_QUALITY" .. rarity]
|
jcallahan@139
|
2537 local npc = NPCEntry(npc_id)
|
jcallahan@139
|
2538 npc.wild_pet = is_wild or nil
|
jcallahan@139
|
2539 npc.battle_pet_data = npc.battle_pet_data or {}
|
jcallahan@139
|
2540 npc.battle_pet_data[rarity_name] = npc.battle_pet_data[rarity_name] or {}
|
jcallahan@139
|
2541 npc.battle_pet_data[rarity_name]["level_" .. level] = npc.battle_pet_data[rarity_name]["level_" .. level] or {}
|
jcallahan@139
|
2542
|
jcallahan@139
|
2543 local data = npc.battle_pet_data[rarity_name]["level_" .. level]
|
jcallahan@139
|
2544 data.max_health = max_health
|
jcallahan@139
|
2545 data.attack = attack
|
jcallahan@139
|
2546 data.speed = speed
|
jcallahan@139
|
2547 end
|
jcallahan@115
|
2548 end
|
jcallahan@115
|
2549 end
|
MMOSimca@368
|
2550 end]]--
|
jcallahan@115
|
2551
|
jcallahan@115
|
2552
|
jcallahan@156
|
2553 function WDP:PLAYER_REGEN_DISABLED(event_name)
|
jcallahan@156
|
2554 private.in_combat = true
|
jcallahan@156
|
2555 end
|
jcallahan@156
|
2556
|
jcallahan@156
|
2557
|
jcallahan@156
|
2558 function WDP:PLAYER_REGEN_ENABLED(event_name)
|
jcallahan@156
|
2559 private.in_combat = nil
|
jcallahan@156
|
2560 end
|
jcallahan@156
|
2561
|
jcallahan@156
|
2562
|
jcallahan@118
|
2563 function WDP:PLAYER_TARGET_CHANGED(event_name)
|
jcallahan@215
|
2564 if not TargetedNPC() then
|
jcallahan@118
|
2565 return
|
jcallahan@2
|
2566 end
|
jcallahan@151
|
2567 current_action.target_type = AF.NPC
|
jcallahan@118
|
2568 self:UpdateTargetLocation()
|
jcallahan@118
|
2569 end
|
jcallahan@2
|
2570
|
jcallahan@89
|
2571
|
jcallahan@12
|
2572 do
|
jcallahan@12
|
2573 local function UpdateQuestJuncture(point)
|
jcallahan@12
|
2574 local unit_name = _G.UnitName("questnpc")
|
jcallahan@9
|
2575
|
jcallahan@12
|
2576 if not unit_name then
|
jcallahan@12
|
2577 return
|
jcallahan@12
|
2578 end
|
jcallahan@34
|
2579 local unit_type, unit_id = ParseGUID(_G.UnitGUID("questnpc"))
|
MMOSimca@351
|
2580 Debug("UpdateQuestJuncture: Updating quest juncture for %s.", ("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id))
|
jcallahan@12
|
2581 if unit_type == private.UNIT_TYPES.OBJECT then
|
jcallahan@38
|
2582 UpdateDBEntryLocation("objects", unit_id)
|
jcallahan@12
|
2583 end
|
jcallahan@19
|
2584 local quest = DBEntry("quests", _G.GetQuestID())
|
jcallahan@12
|
2585 quest[point] = quest[point] or {}
|
MMOSimca@329
|
2586 quest[point][("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id)] = true
|
jcallahan@24
|
2587
|
jcallahan@24
|
2588 return quest
|
jcallahan@12
|
2589 end
|
jcallahan@10
|
2590
|
jcallahan@12
|
2591
|
jcallahan@92
|
2592 function WDP:QUEST_COMPLETE(event_name)
|
jcallahan@97
|
2593 local quest = UpdateQuestJuncture("end")
|
catherton@465
|
2594
|
MMOSimca@446
|
2595 if not quest then
|
MMOSimca@446
|
2596 return
|
MMOSimca@446
|
2597 end
|
jcallahan@97
|
2598
|
jcallahan@112
|
2599 if ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@112
|
2600 quest.reward_text = ReplaceKeywords(_G.GetRewardText())
|
jcallahan@112
|
2601 end
|
jcallahan@67
|
2602 -- Make sure the quest NPC isn't erroneously recorded as giving reputation for quests which award it.
|
jcallahan@177
|
2603 ClearKilledNPC()
|
jcallahan@10
|
2604 end
|
jcallahan@10
|
2605
|
jcallahan@12
|
2606
|
jcallahan@92
|
2607 function WDP:QUEST_DETAIL(event_name)
|
jcallahan@24
|
2608 local quest = UpdateQuestJuncture("begin")
|
jcallahan@24
|
2609
|
jcallahan@46
|
2610 if not quest then
|
jcallahan@46
|
2611 return
|
jcallahan@46
|
2612 end
|
jcallahan@24
|
2613 quest.classes = quest.classes or {}
|
jcallahan@27
|
2614 quest.classes[PLAYER_CLASS] = true
|
jcallahan@24
|
2615
|
jcallahan@24
|
2616 quest.races = quest.races or {}
|
jcallahan@100
|
2617 quest.races[(PLAYER_RACE == "Pandaren") and ("%s_%s"):format(PLAYER_RACE, PLAYER_FACTION or "Neutral") or PLAYER_RACE] = true
|
jcallahan@10
|
2618 end
|
jcallahan@12
|
2619 end -- do-block
|
jcallahan@9
|
2620
|
jcallahan@9
|
2621
|
jcallahan@92
|
2622 function WDP:QUEST_LOG_UPDATE(event_name)
|
jcallahan@38
|
2623 local selected_quest = _G.GetQuestLogSelection() -- Save current selection to be restored when we're done.
|
jcallahan@36
|
2624 local entry_index, processed_quests = 1, 0
|
jcallahan@36
|
2625 local _, num_quests = _G.GetNumQuestLogEntries()
|
jcallahan@36
|
2626
|
jcallahan@36
|
2627 while processed_quests <= num_quests do
|
MMOSimca@329
|
2628 local _, _, _, is_header, _, _, _, quest_id = _G.GetQuestLogTitle(entry_index)
|
jcallahan@36
|
2629
|
jcallahan@84
|
2630 if quest_id == 0 then
|
jcallahan@84
|
2631 processed_quests = processed_quests + 1
|
jcallahan@84
|
2632 elseif not is_header then
|
jcallahan@36
|
2633 _G.SelectQuestLogEntry(entry_index);
|
jcallahan@36
|
2634
|
jcallahan@36
|
2635 local quest = DBEntry("quests", quest_id)
|
jcallahan@36
|
2636 quest.timer = _G.GetQuestLogTimeLeft()
|
jcallahan@37
|
2637 quest.can_share = _G.GetQuestLogPushable() and true or nil
|
jcallahan@36
|
2638 processed_quests = processed_quests + 1
|
jcallahan@36
|
2639 end
|
jcallahan@36
|
2640 entry_index = entry_index + 1
|
jcallahan@36
|
2641 end
|
jcallahan@36
|
2642 _G.SelectQuestLogEntry(selected_quest)
|
jcallahan@4
|
2643 self:UnregisterEvent("QUEST_LOG_UPDATE")
|
jcallahan@4
|
2644 end
|
jcallahan@4
|
2645
|
jcallahan@4
|
2646
|
jcallahan@97
|
2647 function WDP:QUEST_PROGRESS(event_name)
|
jcallahan@112
|
2648 if not ALLOWED_LOCALES[CLIENT_LOCALE] then
|
jcallahan@112
|
2649 return
|
jcallahan@112
|
2650 end
|
jcallahan@97
|
2651 DBEntry("quests", _G.GetQuestID()).progress_text = ReplaceKeywords(_G.GetProgressText())
|
jcallahan@97
|
2652 end
|
jcallahan@97
|
2653
|
jcallahan@97
|
2654
|
jcallahan@92
|
2655 function WDP:UNIT_QUEST_LOG_CHANGED(event_name, unit_id)
|
jcallahan@4
|
2656 if unit_id ~= "player" then
|
jcallahan@4
|
2657 return
|
jcallahan@4
|
2658 end
|
jcallahan@4
|
2659 self:RegisterEvent("QUEST_LOG_UPDATE")
|
jcallahan@4
|
2660 end
|
jcallahan@4
|
2661
|
jcallahan@4
|
2662
|
jcallahan@92
|
2663 do
|
jcallahan@92
|
2664 local TRADESKILL_TOOLS = {
|
jcallahan@92
|
2665 Anvil = anvil_spell_ids,
|
jcallahan@92
|
2666 Forge = forge_spell_ids,
|
jcallahan@92
|
2667 }
|
jcallahan@92
|
2668
|
jcallahan@92
|
2669
|
jcallahan@167
|
2670 local function RegisterTools(tradeskill_name, tradeskill_index)
|
catherton@479
|
2671 local link = _G.C_TradeSkillUI.GetRecipeLink(tradeskill_index)
|
catherton@465
|
2672
|
MMOSimca@352
|
2673 if link then
|
MMOSimca@352
|
2674 local spell_id = tonumber(link:match("^|c%x%x%x%x%x%x%x%x|H%w+:(%d+)"))
|
catherton@479
|
2675 local required_tool = _G.C_TradeSkillUI.GetRecipeTools(tradeskill_index)
|
MMOSimca@352
|
2676
|
MMOSimca@352
|
2677 if required_tool then
|
MMOSimca@352
|
2678 for tool_name, registry in pairs(TRADESKILL_TOOLS) do
|
MMOSimca@352
|
2679 if required_tool:find(tool_name) then
|
MMOSimca@352
|
2680 registry[spell_id] = true
|
MMOSimca@352
|
2681 end
|
jcallahan@167
|
2682 end
|
jcallahan@167
|
2683 end
|
jcallahan@167
|
2684 end
|
jcallahan@167
|
2685 end
|
jcallahan@167
|
2686
|
jcallahan@167
|
2687
|
jcallahan@92
|
2688 function WDP:TRADE_SKILL_SHOW(event_name)
|
catherton@479
|
2689 local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
|
jcallahan@92
|
2690
|
jcallahan@92
|
2691 if profession_name == _G.UNKNOWN then
|
jcallahan@92
|
2692 return
|
jcallahan@92
|
2693 end
|
jcallahan@167
|
2694 TradeSkillExecutePer(RegisterTools)
|
jcallahan@92
|
2695 end
|
jcallahan@92
|
2696 end -- do-block
|
jcallahan@92
|
2697
|
jcallahan@92
|
2698
|
jcallahan@167
|
2699 function WDP:TRAINER_CLOSED(event_name)
|
jcallahan@167
|
2700 private.trainer_shown = nil
|
jcallahan@167
|
2701 end
|
jcallahan@167
|
2702
|
jcallahan@167
|
2703
|
jcallahan@92
|
2704 function WDP:TRAINER_SHOW(event_name)
|
jcallahan@232
|
2705 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@164
|
2706 local trainer = NPCEntry(unit_idnum)
|
jcallahan@58
|
2707
|
jcallahan@164
|
2708 if not trainer then
|
jcallahan@58
|
2709 return
|
jcallahan@58
|
2710 end
|
jcallahan@331
|
2711 local _, trainer_standing = UnitFactionStanding("npc")
|
jcallahan@164
|
2712 trainer.teaches = trainer.teaches or {}
|
jcallahan@27
|
2713
|
jcallahan@167
|
2714 private.trainer_shown = true
|
jcallahan@167
|
2715
|
jcallahan@27
|
2716 -- Get the initial trainer filters
|
MMOSimca@344
|
2717 local available = _G.GetTrainerServiceTypeFilter("available") and 1 or 0
|
MMOSimca@344
|
2718 local unavailable = _G.GetTrainerServiceTypeFilter("unavailable") and 1 or 0
|
MMOSimca@344
|
2719 local used = _G.GetTrainerServiceTypeFilter("used") and 1 or 0
|
jcallahan@27
|
2720
|
jcallahan@27
|
2721 -- Clear the trainer filters
|
MMOSimca@344
|
2722 _G.SetTrainerServiceTypeFilter("available", 1)
|
MMOSimca@344
|
2723 _G.SetTrainerServiceTypeFilter("unavailable", 1)
|
MMOSimca@344
|
2724 _G.SetTrainerServiceTypeFilter("used", 1)
|
jcallahan@27
|
2725
|
jcallahan@27
|
2726 for index = 1, _G.GetNumTrainerServices(), 1 do
|
jcallahan@27
|
2727 local spell_name, rank_name, _, _, required_level = _G.GetTrainerServiceInfo(index)
|
jcallahan@27
|
2728
|
jcallahan@27
|
2729 if spell_name then
|
jcallahan@27
|
2730 DatamineTT:ClearLines()
|
jcallahan@27
|
2731 DatamineTT:SetTrainerService(index)
|
jcallahan@27
|
2732
|
jcallahan@27
|
2733 local _, _, spell_id = DatamineTT:GetSpell()
|
jcallahan@27
|
2734
|
jcallahan@43
|
2735 if spell_id then
|
jcallahan@164
|
2736 local class_professions = trainer.teaches[PLAYER_CLASS]
|
jcallahan@164
|
2737
|
jcallahan@164
|
2738 if not class_professions then
|
jcallahan@164
|
2739 trainer.teaches[PLAYER_CLASS] = {}
|
jcallahan@164
|
2740 class_professions = trainer.teaches[PLAYER_CLASS]
|
jcallahan@164
|
2741 end
|
jcallahan@43
|
2742 local profession, min_skill = _G.GetTrainerServiceSkillReq(index)
|
jcallahan@43
|
2743 profession = profession or "General"
|
jcallahan@43
|
2744
|
jcallahan@164
|
2745 local profession_skills = class_professions[profession]
|
jcallahan@43
|
2746
|
jcallahan@43
|
2747 if not profession_skills then
|
jcallahan@43
|
2748 class_professions[profession] = {}
|
jcallahan@43
|
2749 profession_skills = class_professions[profession]
|
jcallahan@43
|
2750 end
|
jcallahan@173
|
2751 profession_skills[spell_id] = ("%d:%d:%d"):format(required_level, min_skill, _G.GetTrainerServiceCost(index))
|
jcallahan@27
|
2752 end
|
jcallahan@27
|
2753 end
|
jcallahan@27
|
2754 end
|
jcallahan@27
|
2755 -- Reset the filters to what they were before
|
MMOSimca@344
|
2756 _G.SetTrainerServiceTypeFilter("available", available or 0)
|
MMOSimca@344
|
2757 _G.SetTrainerServiceTypeFilter("unavailable", unavailable or 0)
|
MMOSimca@344
|
2758 _G.SetTrainerServiceTypeFilter("used", used or 0)
|
jcallahan@27
|
2759 end
|
jcallahan@27
|
2760
|
jcallahan@27
|
2761
|
jcallahan@1
|
2762 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)
|
jcallahan@1
|
2763 if private.tracked_line or unit_id ~= "player" then
|
jcallahan@1
|
2764 return
|
jcallahan@1
|
2765 end
|
jcallahan@1
|
2766 local spell_label = private.SPELL_LABELS_BY_NAME[spell_name]
|
jcallahan@1
|
2767
|
jcallahan@1
|
2768 if not spell_label then
|
jcallahan@1
|
2769 return
|
jcallahan@1
|
2770 end
|
jcallahan@306
|
2771
|
MMOSimca@343
|
2772 Debug("UNIT_SPELLCAST_SENT: %s was cast.", spell_name)
|
jcallahan@150
|
2773 local item_name, item_link = _G.GameTooltip:GetItem()
|
jcallahan@150
|
2774 local unit_name, unit_id = _G.GameTooltip:GetUnit()
|
jcallahan@1
|
2775
|
jcallahan@150
|
2776 if not unit_name and _G.UnitName("target") == target_name then
|
jcallahan@150
|
2777 unit_name = target_name
|
jcallahan@150
|
2778 unit_id = "target"
|
jcallahan@1
|
2779 end
|
jcallahan@1
|
2780 local spell_flags = private.SPELL_FLAGS_BY_LABEL[spell_label]
|
jcallahan@28
|
2781 local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
|
MMOSimca@328
|
2782 if not (zone_name and area_id and x and y and map_level) then
|
catherton@468
|
2783 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
|
2784 return
|
MMOSimca@328
|
2785 end
|
jcallahan@28
|
2786
|
jcallahan@205
|
2787 table.wipe(current_action)
|
jcallahan@122
|
2788 current_action.instance_token = instance_token
|
jcallahan@122
|
2789 current_action.map_level = map_level
|
jcallahan@122
|
2790 current_action.x = x
|
jcallahan@122
|
2791 current_action.y = y
|
jcallahan@122
|
2792 current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
|
jcallahan@122
|
2793 current_action.spell_label = spell_label
|
jcallahan@105
|
2794
|
jcallahan@105
|
2795 if not private.NON_LOOT_SPELL_LABELS[spell_label] then
|
jcallahan@122
|
2796 current_action.loot_label = spell_label:lower()
|
jcallahan@105
|
2797 end
|
jcallahan@1
|
2798
|
jcallahan@151
|
2799 if unit_name and unit_name == target_name and not item_name then
|
jcallahan@16
|
2800 if bit.band(spell_flags, AF.NPC) == AF.NPC then
|
jcallahan@150
|
2801 if not unit_id or unit_name ~= target_name then
|
jcallahan@16
|
2802 return
|
jcallahan@16
|
2803 end
|
jcallahan@123
|
2804 current_action.target_type = AF.NPC
|
jcallahan@16
|
2805 end
|
jcallahan@16
|
2806 elseif bit.band(spell_flags, AF.ITEM) == AF.ITEM then
|
jcallahan@123
|
2807 current_action.target_type = AF.ITEM
|
jcallahan@16
|
2808
|
jcallahan@150
|
2809 if item_name and item_name == target_name then
|
jcallahan@150
|
2810 current_action.identifier = ItemLinkToID(item_link)
|
jcallahan@16
|
2811 elseif target_name and target_name ~= "" then
|
jcallahan@331
|
2812 local _, item_link = _G.GetItemInfo(target_name)
|
jcallahan@331
|
2813 current_action.identifier = ItemLinkToID(item_link)
|
jcallahan@16
|
2814 end
|
jcallahan@150
|
2815 elseif not item_name and not unit_name then
|
jcallahan@1
|
2816 if bit.band(spell_flags, AF.OBJECT) == AF.OBJECT then
|
jcallahan@17
|
2817 if target_name == "" then
|
jcallahan@17
|
2818 return
|
jcallahan@17
|
2819 end
|
jcallahan@122
|
2820 current_action.object_name = target_name
|
jcallahan@123
|
2821 current_action.target_type = AF.OBJECT
|
jcallahan@1
|
2822 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then
|
jcallahan@123
|
2823 current_action.target_type = AF.ZONE
|
jcallahan@1
|
2824 end
|
jcallahan@1
|
2825 end
|
jcallahan@1
|
2826 private.tracked_line = spell_line
|
jcallahan@0
|
2827 end
|
jcallahan@0
|
2828
|
jcallahan@94
|
2829
|
MMOSimca@393
|
2830 -- Triggered by bonus roll prompts, disenchant prompts, and in a few other rare circumstances
|
jcallahan@312
|
2831 function WDP:SPELL_CONFIRMATION_PROMPT(event_name, spell_id, confirm_type, text, duration, currency_id_cost)
|
jcallahan@306
|
2832 if private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id] then
|
jcallahan@306
|
2833 ClearKilledBossID()
|
jcallahan@306
|
2834 ClearLootToastContainerID()
|
MMOSimca@387
|
2835 raid_boss_id = private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id]
|
jcallahan@306
|
2836 else
|
MMOSimca@336
|
2837 Debug("%s: Spell ID %d is not a known raid boss 'Bonus' spell.", event_name, spell_id)
|
jcallahan@306
|
2838 return
|
jcallahan@1
|
2839 end
|
jcallahan@306
|
2840
|
jcallahan@324
|
2841 -- Assign existing loot data to boss if it exists
|
jcallahan@307
|
2842 if loot_toast_data then
|
MMOSimca@427
|
2843 local npc = NPCEntry(raid_boss_id)
|
MMOSimca@427
|
2844 if npc then
|
MMOSimca@427
|
2845 -- Create needed npc fields if required
|
MMOSimca@427
|
2846 local loot_label = "drops"
|
MMOSimca@427
|
2847 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
|
MMOSimca@427
|
2848 encounter_data[loot_label] = encounter_data[loot_label] or {}
|
MMOSimca@427
|
2849 encounter_data.loot_counts = encounter_data.loot_counts or {}
|
MMOSimca@427
|
2850
|
MMOSimca@427
|
2851 for index = 1, #loot_toast_data do
|
MMOSimca@427
|
2852 local data = loot_toast_data[index]
|
MMOSimca@427
|
2853 local loot_type = data[1]
|
MMOSimca@427
|
2854 local hyperlink = data[2]
|
MMOSimca@427
|
2855 local quantity = data[3]
|
MMOSimca@427
|
2856
|
MMOSimca@427
|
2857 if loot_type == "item" then
|
MMOSimca@427
|
2858 local item_id = ItemLinkToID(hyperlink)
|
MMOSimca@427
|
2859 Debug("%s: Assigned stored item loot data - %s - %d:%d", event_name, hyperlink, item_id, quantity)
|
MMOSimca@427
|
2860 table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
|
MMOSimca@427
|
2861 elseif loot_type == "money" then
|
MMOSimca@427
|
2862 Debug("%s: Assigned stored money loot data - money:%d", event_name, quantity)
|
MMOSimca@427
|
2863 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
|
MMOSimca@427
|
2864 elseif loot_type == "currency" then
|
MMOSimca@427
|
2865 local currency_texture = CurrencyLinkToTexture(hyperlink)
|
MMOSimca@427
|
2866 Debug("%s: Assigned stored currency loot data - %s - currency:%d:%s", event_name, hyperlink, currency_texture, quantity)
|
MMOSimca@427
|
2867 table.insert(encounter_data[loot_label], ("currency:%d:%s"):format(quantity, currency_texture))
|
MMOSimca@427
|
2868 end
|
jcallahan@317
|
2869 end
|
jcallahan@317
|
2870
|
MMOSimca@427
|
2871 if not boss_loot_toasting[raid_boss_id] then
|
MMOSimca@427
|
2872 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
|
MMOSimca@427
|
2873 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
|
jcallahan@307
|
2874 end
|
MMOSimca@427
|
2875 else
|
MMOSimca@427
|
2876 Debug("%s: NPC is nil, but we have stored loot data...", event_name)
|
jcallahan@307
|
2877 end
|
jcallahan@307
|
2878 end
|
jcallahan@307
|
2879
|
jcallahan@307
|
2880 ClearLootToastData()
|
MMOSimca@427
|
2881 killed_boss_id_timer_handle = C_Timer.NewTimer(5, ClearKilledBossID)
|
jcallahan@306
|
2882 end
|
jcallahan@306
|
2883
|
jcallahan@306
|
2884
|
jcallahan@306
|
2885 function WDP:UNIT_SPELLCAST_SUCCEEDED(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
|
jcallahan@306
|
2886 if unit_id ~= "player" then
|
jcallahan@306
|
2887 return
|
jcallahan@306
|
2888 end
|
jcallahan@306
|
2889 private.tracked_line = nil
|
jcallahan@306
|
2890 private.previous_spell_id = spell_id
|
jcallahan@306
|
2891
|
MMOSimca@393
|
2892 -- For spells cast when Logging
|
MMOSimca@345
|
2893 if private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id] then
|
MMOSimca@345
|
2894 last_timber_spell_id = spell_id
|
MMOSimca@351
|
2895 UpdateDBEntryLocation("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id]))
|
MMOSimca@345
|
2896 return
|
MMOSimca@345
|
2897 end
|
MMOSimca@345
|
2898
|
MMOSimca@393
|
2899 -- For spells cast by items that always trigger loot toasts
|
MMOSimca@381
|
2900 if private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id] then
|
jcallahan@306
|
2901 ClearKilledBossID()
|
jcallahan@306
|
2902 ClearLootToastContainerID()
|
jcallahan@307
|
2903 ClearLootToastData()
|
jcallahan@306
|
2904
|
MMOSimca@387
|
2905 loot_toast_container_id = private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
|
MMOSimca@383
|
2906 loot_toast_container_timer_handle = C_Timer.NewTimer(1, ClearLootToastContainerID) -- we need to assign a handle here to cancel it later
|
MMOSimca@345
|
2907 return
|
jcallahan@306
|
2908 end
|
jcallahan@306
|
2909
|
MMOSimca@393
|
2910 -- For spells cast by items that don't usually trigger loot toasts
|
catherton@473
|
2911 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
|
2912 -- Set up timer
|
MMOSimca@393
|
2913 ClearChatLootData()
|
MMOSimca@393
|
2914 Debug("%s: Beginning chat-based loot timer for spellID %d", event_name, spell_id)
|
MMOSimca@411
|
2915 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
|
catherton@473
|
2916 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
|
2917 chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID]
|
MMOSimca@454
|
2918 else
|
MMOSimca@454
|
2919 chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
|
MMOSimca@454
|
2920 end
|
MMOSimca@347
|
2921 return
|
MMOSimca@347
|
2922 end
|
MMOSimca@347
|
2923
|
jcallahan@306
|
2924 if anvil_spell_ids[spell_id] then
|
jcallahan@306
|
2925 UpdateDBEntryLocation("objects", OBJECT_ID_ANVIL)
|
jcallahan@306
|
2926 elseif forge_spell_ids[spell_id] then
|
jcallahan@306
|
2927 UpdateDBEntryLocation("objects", OBJECT_ID_FORGE)
|
jcallahan@306
|
2928 elseif spell_name:match("^Harvest.+") then
|
jcallahan@306
|
2929 killed_npc_id = current_target_id
|
MMOSimca@343
|
2930 private.harvesting = true -- Used to track which NPCs can be harvested (can we get this from CreatureCache instead?)
|
jcallahan@306
|
2931 end
|
jcallahan@306
|
2932 end
|
jcallahan@0
|
2933
|
jcallahan@90
|
2934
|
jcallahan@1
|
2935 function WDP:HandleSpellFailure(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
|
jcallahan@1
|
2936 if unit_id ~= "player" then
|
jcallahan@1
|
2937 return
|
jcallahan@1
|
2938 end
|
jcallahan@0
|
2939
|
jcallahan@1
|
2940 if private.tracked_line == spell_line then
|
jcallahan@1
|
2941 private.tracked_line = nil
|
jcallahan@1
|
2942 end
|
jcallahan@147
|
2943 table.wipe(current_action)
|
jcallahan@0
|
2944 end
|
jcallahan@90
|
2945
|
jcallahan@90
|
2946
|
jcallahan@90
|
2947 do
|
jcallahan@90
|
2948 local function SetUnitField(field, required_type)
|
jcallahan@90
|
2949 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@90
|
2950
|
jcallahan@90
|
2951 if not unit_idnum or (required_type and unit_type ~= required_type) then
|
jcallahan@90
|
2952 return
|
jcallahan@90
|
2953 end
|
jcallahan@90
|
2954
|
jcallahan@171
|
2955 if UnitTypeIsNPC(unit_type) then
|
jcallahan@90
|
2956 NPCEntry(unit_idnum)[field] = true
|
jcallahan@90
|
2957 elseif unit_type == private.UNIT_TYPES.OBJECT then
|
jcallahan@90
|
2958 DBEntry("objects", unit_idnum)[field] = true
|
jcallahan@93
|
2959 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@90
|
2960 end
|
jcallahan@90
|
2961 end
|
jcallahan@90
|
2962
|
jcallahan@90
|
2963
|
jcallahan@90
|
2964 function WDP:AUCTION_HOUSE_SHOW(event_name)
|
MMOSimca@436
|
2965 WDP:StopChatLootRecording(event_name)
|
jcallahan@90
|
2966 SetUnitField("auctioneer", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2967 end
|
jcallahan@90
|
2968
|
jcallahan@90
|
2969
|
jcallahan@90
|
2970 function WDP:BANKFRAME_OPENED(event_name)
|
MMOSimca@436
|
2971 WDP:StopChatLootRecording(event_name)
|
jcallahan@90
|
2972 SetUnitField("banker", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2973 end
|
jcallahan@90
|
2974
|
jcallahan@90
|
2975
|
jcallahan@90
|
2976 function WDP:BATTLEFIELDS_SHOW(event_name)
|
jcallahan@90
|
2977 SetUnitField("battlemaster", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2978 end
|
jcallahan@90
|
2979
|
jcallahan@90
|
2980
|
jcallahan@92
|
2981 function WDP:FORGE_MASTER_OPENED(event_name)
|
jcallahan@90
|
2982 SetUnitField("arcane_reforger", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
2983 end
|
jcallahan@90
|
2984
|
jcallahan@90
|
2985
|
jcallahan@323
|
2986 local GOSSIP_SHOW_FUNCS = {
|
jcallahan@323
|
2987 [private.UNIT_TYPES.NPC] = function(unit_idnum)
|
jcallahan@323
|
2988 local gossip_options = { _G.GetGossipOptions() }
|
jcallahan@323
|
2989
|
jcallahan@323
|
2990 for index = 2, #gossip_options, 2 do
|
jcallahan@323
|
2991 if gossip_options[index] == "binder" then
|
jcallahan@323
|
2992 SetUnitField("innkeeper", private.UNIT_TYPES.NPC)
|
jcallahan@323
|
2993 return
|
jcallahan@323
|
2994 end
|
jcallahan@323
|
2995 end
|
jcallahan@323
|
2996 end,
|
jcallahan@323
|
2997 [private.UNIT_TYPES.OBJECT] = function(unit_idnum)
|
jcallahan@323
|
2998 UpdateDBEntryLocation("objects", unit_idnum)
|
jcallahan@323
|
2999 end,
|
jcallahan@323
|
3000 }
|
jcallahan@323
|
3001
|
jcallahan@323
|
3002
|
jcallahan@92
|
3003 function WDP:GOSSIP_SHOW(event_name)
|
MMOSimca@436
|
3004 WDP:StopChatLootRecording(event_name)
|
jcallahan@323
|
3005 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
|
jcallahan@323
|
3006 if not unit_idnum then
|
jcallahan@323
|
3007 return
|
jcallahan@323
|
3008 end
|
jcallahan@323
|
3009
|
jcallahan@323
|
3010 if GOSSIP_SHOW_FUNCS[unit_type] then
|
jcallahan@323
|
3011 GOSSIP_SHOW_FUNCS[unit_type](unit_idnum)
|
jcallahan@90
|
3012 end
|
jcallahan@90
|
3013 end
|
jcallahan@90
|
3014
|
jcallahan@90
|
3015
|
jcallahan@93
|
3016 function WDP:GUILDBANKFRAME_OPENED(event_name)
|
MMOSimca@436
|
3017 WDP:StopChatLootRecording(event_name)
|
jcallahan@93
|
3018 SetUnitField("guild_bank", private.UNIT_TYPES.OBJECT)
|
jcallahan@93
|
3019 end
|
jcallahan@93
|
3020
|
jcallahan@93
|
3021
|
jcallahan@189
|
3022 function WDP:ITEM_UPGRADE_MASTER_OPENED(event_name)
|
jcallahan@189
|
3023 SetUnitField("item_upgrade_master", private.UNIT_TYPES.NPC)
|
jcallahan@189
|
3024 end
|
jcallahan@189
|
3025
|
jcallahan@189
|
3026
|
jcallahan@90
|
3027 function WDP:TAXIMAP_OPENED(event_name)
|
jcallahan@90
|
3028 SetUnitField("flight_master", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
3029 end
|
jcallahan@90
|
3030
|
jcallahan@90
|
3031
|
jcallahan@90
|
3032 function WDP:TRANSMOGRIFY_OPEN(event_name)
|
jcallahan@90
|
3033 SetUnitField("transmogrifier", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
3034 end
|
jcallahan@90
|
3035
|
jcallahan@90
|
3036
|
jcallahan@90
|
3037 function WDP:VOID_STORAGE_OPEN(event_name)
|
jcallahan@90
|
3038 SetUnitField("void_storage", private.UNIT_TYPES.NPC)
|
jcallahan@90
|
3039 end
|
jcallahan@90
|
3040 end -- do-block
|