comparison Main.lua @ 22:7e4ce6371608

Take instance difficulty into account for locations. Record locations based on GUID within the NPC id so only one set of location data exists per unique NPC.
author James D. Callahan III <jcallahan@curse.com>
date Thu, 10 May 2012 12:00:50 -0500
parents a82c5d1134db
children 2ff0171bddae
comparison
equal deleted inserted replaced
21:a82c5d1134db 22:7e4ce6371608
84 end 84 end
85 return unit 85 return unit
86 end 86 end
87 87
88 88
89 local function InstanceDifficultyToken()
90 local _, instance_type, instance_difficulty, difficulty_name, _, _, is_dynamic = _G.GetInstanceInfo()
91 if difficulty_name == "" then
92 difficulty_name = "NONE"
93 end
94 return ("%s:%s:%s"):format(instance_type:upper(), difficulty_name:upper():gsub(" ", "_"), _G.tostring(is_dynamic))
95 end
96
97
89 local function CurrentLocationData() 98 local function CurrentLocationData()
90 local map_level = _G.GetCurrentMapDungeonLevel() or 0 99 local map_level = _G.GetCurrentMapDungeonLevel() or 0
91 local x, y = _G.GetPlayerMapPosition("player") 100 local x, y = _G.GetPlayerMapPosition("player")
92 101
93 x = x or 0 102 x = x or 0
107 end 116 end
108 117
109 if _G.DungeonUsesTerrainMap() then 118 if _G.DungeonUsesTerrainMap() then
110 map_level = map_level - 1 119 map_level = map_level - 1
111 end 120 end
112 local _, instance_type = _G.IsInInstance() 121 return _G.GetRealZoneText(), ("%.2f"):format(x * 100), ("%.2f"):format(y * 100), map_level or 0, InstanceDifficultyToken()
113 return _G.GetRealZoneText(), ("%.2f"):format(x * 100), ("%.2f"):format(y * 100), map_level or 0, instance_type:upper()
114 end 122 end
115 123
116 124
117 local function ItemLinkToID(item_link) 125 local function ItemLinkToID(item_link)
118 if not item_link then 126 if not item_link then
143 151
144 local function UpdateObjectLocation(identifier) 152 local function UpdateObjectLocation(identifier)
145 if not identifier then 153 if not identifier then
146 return 154 return
147 end 155 end
148 local zone_name, x, y, map_level, instance_type = CurrentLocationData() 156 local zone_name, x, y, map_level, instance_token = CurrentLocationData()
149 local object = DBEntry("objects", identifier) 157 local object = DBEntry("objects", identifier)
150 object.locations = object.locations or {} 158 object.locations = object.locations or {}
151 159
152 if not object.locations[zone_name] then 160 if not object.locations[zone_name] then
153 object.locations[zone_name] = {} 161 object.locations[zone_name] = {}
154 end 162 end
155 object.locations[zone_name][("%s:%s:%s:%s"):format(instance_type, map_level, x, y)] = true 163 object.locations[zone_name][("%s:%s:%s:%s"):format(instance_token, map_level, x, y)] = true
156 end 164 end
157 165
158 166
159 local function HandleItemUse(item_link, bag_index, slot_index) 167 local function HandleItemUse(item_link, bag_index, slot_index)
160 if not item_link then 168 if not item_link then
295 end 303 end
296 end 304 end
297 305
298 306
299 function WDP:UpdateTargetLocation() 307 function WDP:UpdateTargetLocation()
300 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or _G.UnitIsTapped("target") then 308 local is_dead = _G.UnitIsDead("target")
309
310 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or (_G.UnitIsTapped("target") and not is_dead) then
301 return 311 return
302 end 312 end
303 313
304 for index = 1, 4 do 314 for index = 1, 4 do
305 if not _G.CheckInteractDistance("target", index) then 315 if not _G.CheckInteractDistance("target", index) then
306 return 316 return
307 end 317 end
308 end 318 end
309 319 local target_guid = _G.UnitGUID("target")
310 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target")) 320 local unit_type, unit_idnum = self:ParseGUID(target_guid)
311 321
312 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then 322 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
313 return 323 return
314 end 324 end
315 local zone_name, x, y, map_level, instance_type = CurrentLocationData() 325 local zone_name, x, y, map_level, instance_token = CurrentLocationData()
316 local npc_data = DBEntry("npcs", unit_idnum).stats[("level_%d"):format(_G.UnitLevel("target"))] 326 local npc_data = DBEntry("npcs", unit_idnum).encounter_data[("level_%d"):format(_G.UnitLevel("target"))]
317 npc_data.locations = npc_data.locations or {} 327 npc_data.locations = npc_data.locations or {}
318 328
319 if not npc_data.locations[zone_name] then 329 if not npc_data.locations[zone_name] then
320 npc_data.locations[zone_name] = {} 330 npc_data.locations[zone_name] = {}
321 end 331 end
322 npc_data.locations[zone_name][("%s:%s:%s:%s"):format(instance_type, map_level, x, y)] = true 332
333 -- Only record corpse location if there is no entry for this GUID.
334 if is_dead and npc_data.locations[zone_name][target_guid] then
335 return
336 end
337 npc_data.locations[zone_name][target_guid] = ("%s:%s:%s:%s"):format(instance_token, map_level, x, y)
323 end 338 end
324 339
325 340
326 ----------------------------------------------------------------------- 341 -----------------------------------------------------------------------
327 -- Event handlers. 342 -- Event handlers.
330 local npc = DBEntry("npcs", action_data.id_num) 345 local npc = DBEntry("npcs", action_data.id_num)
331 346
332 if not npc then 347 if not npc then
333 return 348 return
334 end 349 end
335 npc.stats[action_data.npc_level].reputations = npc.stats[action_data.npc_level].reputations or {} 350 npc.encounter_data[action_data.npc_level].reputations = npc.encounter_data[action_data.npc_level].reputations or {}
336 npc.stats[action_data.npc_level].reputations[faction_name] = amount 351 npc.encounter_data[action_data.npc_level].reputations[faction_name] = amount
337 end 352 end
338 353
339 354
340 function WDP:LOOT_CLOSED() 355 function WDP:LOOT_CLOSED()
341 -- table.wipe(action_data) 356 -- table.wipe(action_data)
395 return action_data.loot_type and _G.IsFishingLoot() 410 return action_data.loot_type and _G.IsFishingLoot()
396 end, 411 end,
397 } 412 }
398 413
399 414
415 local function GenericLootUpdate(data_type)
416 local entry = DBEntry(data_type, action_data.id_num)
417
418 if not entry then
419 return
420 end
421 local loot_type = action_data.loot_type or "drops"
422 entry[loot_type] = entry[loot_type] or {}
423
424 for index = 1, #action_data.loot_list do
425 table.insert(entry[loot_type], action_data.loot_list[index])
426 end
427 end
428
429
400 local LOOT_UPDATE_FUNCS = { 430 local LOOT_UPDATE_FUNCS = {
401 [AF.ITEM] = function() 431 [AF.ITEM] = function()
402 local item = DBEntry("items", action_data.item_id) 432 local item = DBEntry("items", action_data.item_id)
403 local loot_type = action_data.loot_type or "drops" 433 local loot_type = action_data.loot_type or "drops"
404 item[loot_type] = item[loot_type] or {} 434 item[loot_type] = item[loot_type] or {}
406 for index = 1, #action_data.loot_list do 436 for index = 1, #action_data.loot_list do
407 table.insert(item[loot_type], action_data.loot_list[index]) 437 table.insert(item[loot_type], action_data.loot_list[index])
408 end 438 end
409 end, 439 end,
410 [AF.NPC] = function() 440 [AF.NPC] = function()
411 local npc = DBEntry("npcs", action_data.id_num) 441 GenericLootUpdate("npcs")
412
413 if not npc then
414 return
415 end
416 local loot_type = action_data.loot_type or "drops"
417 npc[loot_type] = npc[loot_type] or {}
418
419 for index = 1, #action_data.loot_list do
420 table.insert(npc[loot_type], action_data.loot_list[index])
421 end
422 end, 442 end,
423 [AF.OBJECT] = function() 443 [AF.OBJECT] = function()
424 local object = DBEntry("objects", action_data.identifier) 444 GenericLootUpdate("objects")
425 object.drops = object.drops or {}
426
427 for index = 1, #action_data.loot_list do
428 table.insert(object.drops, action_data.loot_list[index])
429 end
430 end, 445 end,
431 [AF.ZONE] = function() 446 [AF.ZONE] = function()
432 local loot_type = action_data.loot_type or "drops" 447 local loot_type = action_data.loot_type or "drops"
433 local zone = DBEntry("zones", action_data.zone) 448 local zone = DBEntry("zones", action_data.zone)
434 zone[loot_type] = zone[loot_type] or {} 449 zone[loot_type] = zone[loot_type] or {}
435 450
436 local location_data = ("%s:%s:%s:%s"):format(action_data.instance_type, action_data.map_level, action_data.x, action_data.y) 451 local location_data = ("%s:%s:%s:%s"):format(action_data.instance_token, action_data.map_level, action_data.x, action_data.y)
437 local loot_data = zone[loot_type][location_data] 452 local loot_data = zone[loot_type][location_data]
438 453
439 if not loot_data then 454 if not loot_data then
440 zone[loot_type][location_data] = {} 455 zone[loot_type][location_data] = {}
441 loot_data = zone[loot_type][location_data] 456 loot_data = zone[loot_type][location_data]
655 end 670 end
656 end 671 end
657 npc.gender = GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED" 672 npc.gender = GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"
658 npc.is_pvp = _G.UnitIsPVP("target") and true or nil 673 npc.is_pvp = _G.UnitIsPVP("target") and true or nil
659 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), REACTION_NAMES[_G.UnitReaction("player", "target")]) 674 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), REACTION_NAMES[_G.UnitReaction("player", "target")])
660 npc.stats = npc.stats or {} 675 npc.encounter_data = npc.encounter_data or {}
661 676
662 local npc_level = ("level_%d"):format(_G.UnitLevel("target")) 677 local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
663 678
664 if not npc.stats[npc_level] then 679 if not npc.encounter_data[npc_level] then
665 npc.stats[npc_level] = { 680 npc.encounter_data[npc_level] = {
666 max_health = _G.UnitHealthMax("target"), 681 max_health = _G.UnitHealthMax("target"),
667 } 682 }
668 683
669 local max_power = _G.UnitManaMax("target") 684 local max_power = _G.UnitManaMax("target")
670 685
671 if max_power > 0 then 686 if max_power > 0 then
672 local power_type = _G.UnitPowerType("target") 687 local power_type = _G.UnitPowerType("target")
673 npc.stats[npc_level].power = ("%s:%d"):format(POWER_TYPE_NAMES[_G.tostring(power_type)] or power_type, max_power) 688 npc.encounter_data[npc_level].power = ("%s:%d"):format(POWER_TYPE_NAMES[_G.tostring(power_type)] or power_type, max_power)
674 end 689 end
675 end 690 end
676 table.wipe(action_data) 691 table.wipe(action_data)
677 action_data.type = AF.NPC 692 action_data.type = AF.NPC
678 action_data.id_num = unit_idnum 693 action_data.id_num = unit_idnum
759 elseif target_name and target_name ~= "" then 774 elseif target_name and target_name ~= "" then
760 local _, target_item_link = _G.GetItemInfo(target_name) 775 local _, target_item_link = _G.GetItemInfo(target_name)
761 action_data.item_id = ItemLinkToID(target_item_link) 776 action_data.item_id = ItemLinkToID(target_item_link)
762 end 777 end
763 elseif not tt_item_name and not tt_unit_name then 778 elseif not tt_item_name and not tt_unit_name then
764 local zone_name, x, y, map_level, instance_type = CurrentLocationData() 779 local zone_name, x, y, map_level, instance_token = CurrentLocationData()
765 780
766 action_data.instance_type = instance_type 781 action_data.instance_token = instance_token
767 action_data.map_level = map_level 782 action_data.map_level = map_level
768 action_data.name = target_name 783 action_data.name = target_name
769 action_data.x = x 784 action_data.x = x
770 action_data.y = y 785 action_data.y = y
771 action_data.zone = zone_name 786 action_data.zone = zone_name