comparison Main.lua @ 2:d563ea0ec911

Added recording of NPC locations (with coordinates and map level), unit reactions, health, power, power-type, and level.
author James D. Callahan III <jcallahan@curse.com>
date Fri, 27 Apr 2012 08:22:37 -0500
parents d9375a473042
children a9b84f0d8235
comparison
equal deleted inserted replaced
1:d9375a473042 2:d563ea0ec911
65 -- PET_STABLE_SHOW = true, 65 -- PET_STABLE_SHOW = true,
66 -- PLAYER_ALIVE = true, 66 -- PLAYER_ALIVE = true,
67 -- PLAYER_ENTERING_WORLD = HandleZoneChange, 67 -- PLAYER_ENTERING_WORLD = HandleZoneChange,
68 -- PLAYER_LOGIN = true, 68 -- PLAYER_LOGIN = true,
69 -- PLAYER_LOGOUT = true, 69 -- PLAYER_LOGOUT = true,
70 -- PLAYER_TARGET_CHANGED = true, 70 PLAYER_TARGET_CHANGED = true,
71 -- QUEST_COMPLETE = true, 71 -- QUEST_COMPLETE = true,
72 -- QUEST_DETAIL = true, 72 -- QUEST_DETAIL = true,
73 -- QUEST_LOG_UPDATE = true, 73 -- QUEST_LOG_UPDATE = true,
74 -- QUEST_PROGRESS = true, 74 -- QUEST_PROGRESS = true,
75 -- TAXIMAP_OPENED = true, 75 -- TAXIMAP_OPENED = true,
91 ----------------------------------------------------------------------- 91 -----------------------------------------------------------------------
92 -- Local variables. 92 -- Local variables.
93 ----------------------------------------------------------------------- 93 -----------------------------------------------------------------------
94 local db 94 local db
95 local durability_timer_handle 95 local durability_timer_handle
96 local target_location_timer_handle
96 local action_data = {} 97 local action_data = {}
97 98
98 do 99 do
99 local UNIT_TYPE_BITMASK = 0x007 100 local UNIT_TYPE_BITMASK = 0x007
100 101
135 end 136 end
136 137
137 if _G.DungeonUsesTerrainMap() then 138 if _G.DungeonUsesTerrainMap() then
138 map_level = map_level - 1 139 map_level = map_level - 1
139 end 140 end
140 141 return _G.GetRealZoneText(), ("%.2f"):format(x * 100), ("%.2f"):format(y * 100), map_level or 0
141 return _G.GetRealZoneText(), math.floor(x * 1000 + 0.5), math.floor(y * 1000 + 0.5), map_level or 0
142 end 142 end
143 143
144 144
145 local function ItemLinkToID(item_link) 145 local function ItemLinkToID(item_link)
146 if not item_link then 146 if not item_link then
161 function WDP:OnEnable() 161 function WDP:OnEnable()
162 for event_name, mapping in pairs(EVENT_MAPPING) do 162 for event_name, mapping in pairs(EVENT_MAPPING) do
163 self:RegisterEvent(event_name, (_G.type(mapping) ~= "boolean") and mapping or nil) 163 self:RegisterEvent(event_name, (_G.type(mapping) ~= "boolean") and mapping or nil)
164 end 164 end
165 durability_timer_handle = self:ScheduleRepeatingTimer("ProcessDurability", 30) 165 durability_timer_handle = self:ScheduleRepeatingTimer("ProcessDurability", 30)
166 target_location_timer_handle = self:ScheduleRepeatingTimer("UpdateTargetLocation", 0.2)
166 end 167 end
167 168
168 169
169 local function RecordDurability(item_id, durability) 170 local function RecordDurability(item_id, durability)
170 if not durability or durability <= 0 then 171 if not durability or durability <= 0 then
196 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index) 197 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index)
197 RecordDurability(item_id, max_durability) 198 RecordDurability(item_id, max_durability)
198 end 199 end
199 end 200 end
200 end 201 end
202 end
203
204
205 function WDP:UpdateTargetLocation()
206 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or _G.UnitIsTapped("target") then
207 return
208 end
209
210 for index = 1, 4 do
211 if not _G.CheckInteractDistance("target", index) then
212 return
213 end
214 end
215
216 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target"))
217
218 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
219 return
220 end
221 local zone_name, x, y, map_level = CurrentLocationData()
222 local npc_data = db.npcs[unit_idnum].stats[("level_%d"):format(_G.UnitLevel("target"))]
223
224 if not npc_data.locations then
225 npc_data.locations = {}
226 end
227
228 if not npc_data.locations[zone_name] then
229 npc_data.locations[zone_name] = {}
230 end
231 npc_data.locations[zone_name][("%s:%s:%s"):format(map_level, x, y)] = true
201 end 232 end
202 233
203 234
204 ----------------------------------------------------------------------- 235 -----------------------------------------------------------------------
205 -- Event handlers. 236 -- Event handlers.
262 function WDP:LOOT_OPENED() 293 function WDP:LOOT_OPENED()
263 if not action_data.type then 294 if not action_data.type then
264 action_data.type = AF.NPC 295 action_data.type = AF.NPC
265 end 296 end
266 local verify_func = LOOT_VERIFY_FUNCS[action_data.type] 297 local verify_func = LOOT_VERIFY_FUNCS[action_data.type]
267 local update_func = LOOT_UPDATE_FUNCS[action_data.type] 298 local update_func = LOOT_UPDATE_FUNCS[action_data.type]
268 299
269 if not verify_func or not update_func or not verify_func() then 300 if not verify_func or not update_func or not verify_func() then
270 return 301 return
271 end 302 end
272 303
287 318
288 for item_id, quantity in pairs(loot_registry) do 319 for item_id, quantity in pairs(loot_registry) do
289 table.insert(action_data.drops, ("%d:%d"):format(item_id, quantity)) 320 table.insert(action_data.drops, ("%d:%d"):format(item_id, quantity))
290 end 321 end
291 update_func() 322 update_func()
323 end
324
325
326 local GENDER_NAMES = {
327 "UNKNOWN",
328 "MALE",
329 "FEMALE",
330 }
331
332
333 local REACTION_NAMES = {
334 "HATED",
335 "HOSTILE",
336 "UNFRIENDLY",
337 "NEUTRAL",
338 "FRIENDLY",
339 "HONORED",
340 "REVERED",
341 "EXALTED",
342 }
343
344
345 local POWER_TYPE_NAMES = {
346 ["0"] = "MANA",
347 ["1"] = "RAGE",
348 ["2"] = "FOCUS",
349 ["3"] = "ENERGY",
350 ["6"] = "RUNIC_POWER",
351 }
352
353
354 function WDP:PLAYER_TARGET_CHANGED()
355 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") then
356 return
357 end
358 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target"))
359
360 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
361 return
362 end
363
364 local npc = db.npcs[unit_idnum]
365
366 if not npc then
367 db.npcs[unit_idnum] = {}
368 npc = db.npcs[unit_idnum]
369 end
370 local _, class_token = _G.UnitClass("target")
371 npc.class = class_token
372 -- TODO: Add faction here
373 npc.gender = GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"
374 npc.is_pvp = _G.UnitIsPVP("target") and true or false
375 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), REACTION_NAMES[_G.UnitReaction("player", "target")])
376 npc.stats = npc.stats or {}
377
378 local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
379
380 if not npc.stats[npc_level] then
381 local power_type = _G.UnitPowerType("target")
382
383 npc.stats[npc_level] = {
384 max_health = _G.UnitHealthMax("target"),
385 max_power = _G.UnitManaMax("target"),
386 power_type = POWER_TYPE_NAMES[_G.tostring(power_type)] or power_type,
387 }
388 end
292 end 389 end
293 390
294 391
295 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line) 392 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)
296 if private.tracked_line or unit_id ~= "player" then 393 if private.tracked_line or unit_id ~= "player" then
324 action_data.name = target_name 421 action_data.name = target_name
325 action_data.type = AF.OBJECT 422 action_data.type = AF.OBJECT
326 action_data.x = x 423 action_data.x = x
327 action_data.y = y 424 action_data.y = y
328 action_data.zone = zone_name 425 action_data.zone = zone_name
329 print("Found spell flagged for OBJECT") 426 print(("Found spell flagged for OBJECT: %s (%s, %s)"):format(zone_name, x, y))
330 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then 427 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then
331 print("Found spell flagged for ZONE") 428 print("Found spell flagged for ZONE")
332 end 429 end
333 elseif tt_unit_name and not tt_item_name then 430 elseif tt_unit_name and not tt_item_name then
334 if bit.band(spell_flags, AF.NPC) == AF.NPC then 431 if bit.band(spell_flags, AF.NPC) == AF.NPC then