comparison Main.lua @ 78:7179e2938324

Handle loot sources by GUID instead of by ID to get accurate drop counts.
author James D. Callahan III <jcallahan@curse.com>
date Wed, 22 Aug 2012 12:49:42 -0500
parents c483513c7299
children 376d3e03d632
comparison
equal deleted inserted replaced
77:c483513c7299 78:7179e2938324
7 local tonumber = _G.tonumber 7 local tonumber = _G.tonumber
8 8
9 local bit = _G.bit 9 local bit = _G.bit
10 local math = _G.math 10 local math = _G.math
11 local table = _G.table 11 local table = _G.table
12
13 local select = _G.select
12 14
13 15
14 ----------------------------------------------------------------------- 16 -----------------------------------------------------------------------
15 -- AddOn namespace. 17 -- AddOn namespace.
16 ----------------------------------------------------------------------- 18 -----------------------------------------------------------------------
396 function GenericLootUpdate(data_type, top_field) 398 function GenericLootUpdate(data_type, top_field)
397 local loot_type = action_data.label or "drops" 399 local loot_type = action_data.label or "drops"
398 local loot_count = ("%s_count"):format(loot_type) 400 local loot_count = ("%s_count"):format(loot_type)
399 local source_list = {} 401 local source_list = {}
400 402
401 for source_id, loot_data in pairs(action_data.loot_sources) do 403 for source_guid, loot_data in pairs(action_data.loot_sources) do
402 local entry = DBEntry(data_type, source_id) 404 local entry, source_id
405
406 if action_data.type == AF.ITEM then
407 -- Items return the player as the source, so we need to use the item's ID (disenchant, milling, etc)
408 source_id = action_data.identifier
409 entry = DBEntry(data_type, source_id)
410 elseif action_data.type == AF.OBJECT then
411 source_id = ("%s:%s"):format(action_data.spell_label, select(2, ParseGUID(source_guid)))
412 entry = DBEntry(data_type, source_id)
413 else
414 source_id = select(2, ParseGUID(source_guid))
415 entry = DBEntry(data_type, source_id)
416 end
403 417
404 if entry then 418 if entry then
405 local loot_table = LootTable(entry, loot_type, top_field) 419 local loot_table = LootTable(entry, loot_type, top_field)
406 420
407 if not source_list[source_id] then 421 if not source_list[source_guid] then
408 if top_field then 422 if top_field then
409 entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1 423 entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1
410 else 424 else
411 entry[loot_count] = (entry[loot_count] or 0) + 1 425 entry[loot_count] = (entry[loot_count] or 0) + 1
412 end 426 end
413 source_list[source_id] = true 427 source_list[source_guid] = true
414 end 428 end
415 UpdateDBEntryLocation(data_type, source_id) 429 UpdateDBEntryLocation(data_type, source_id)
416 430
417 for item_id, quantity in pairs(loot_data) do 431 for item_id, quantity in pairs(loot_data) do
418 table.insert(loot_table, ("%d:%d"):format(item_id, quantity)) 432 table.insert(loot_table, ("%d:%d"):format(item_id, quantity))
419 end 433 end
420 end 434 end
421 end 435 end
422 -- TODO: Remove this when GetLootSourceInfo() has values for money 436 -- TODO: Remove this when GetLootSourceInfo() has values for money
437 if action_data.type == AF.OBJECT then
438 -- Unfortunately, this means we can't record money from chests...
439 return
440 end
423 local entry = DBEntry(data_type, action_data.identifier) 441 local entry = DBEntry(data_type, action_data.identifier)
424 442
425 if not entry then 443 if not entry then
426 return 444 return
427 end 445 end
841 [AF.NPC] = function() 859 [AF.NPC] = function()
842 local difficulty_token = InstanceDifficultyToken() 860 local difficulty_token = InstanceDifficultyToken()
843 local loot_type = action_data.label or "drops" 861 local loot_type = action_data.label or "drops"
844 local source_list = {} 862 local source_list = {}
845 863
846 for source_id, loot_data in pairs(action_data.loot_sources) do 864 for source_guid, loot_data in pairs(action_data.loot_sources) do
865 local source_id = select(2, ParseGUID(source_guid))
847 local npc = NPCEntry(source_id) 866 local npc = NPCEntry(source_id)
848 867
849 if npc then 868 if npc then
850 local encounter_data = npc.encounter_data[difficulty_token] 869 local encounter_data = npc.encounter_data[difficulty_token]
851 encounter_data[loot_type] = encounter_data[loot_type] or {} 870 encounter_data[loot_type] = encounter_data[loot_type] or {}
852 871
853 if not source_list[source_id] then 872 if not source_list[source_guid] then
854 encounter_data.loot_counts = encounter_data.loot_counts or {} 873 encounter_data.loot_counts = encounter_data.loot_counts or {}
855 encounter_data.loot_counts[loot_type] = (encounter_data.loot_counts[loot_type] or 0) + 1 874 encounter_data.loot_counts[loot_type] = (encounter_data.loot_counts[loot_type] or 0) + 1
856 source_list[source_id] = true 875 source_list[source_id] = true
857 end 876 end
858 877
928 local icon_texture, item_text, quantity, quality, locked = _G.GetLootSlotInfo(loot_slot) 947 local icon_texture, item_text, quantity, quality, locked = _G.GetLootSlotInfo(loot_slot)
929 local slot_type = _G.GetLootSlotType(loot_slot) 948 local slot_type = _G.GetLootSlotType(loot_slot)
930 949
931 -- TODO: Move LOOT_SLOT_X checks within loop when money is detectable via GetLootSourceInfo 950 -- TODO: Move LOOT_SLOT_X checks within loop when money is detectable via GetLootSourceInfo
932 if slot_type == _G.LOOT_SLOT_ITEM then 951 if slot_type == _G.LOOT_SLOT_ITEM then
933 local sources = { 952 local loot_info = {
934 _G.GetLootSourceInfo(loot_slot) 953 _G.GetLootSourceInfo(loot_slot)
935 } 954 }
936 955
937 -- TODO: Remove debugging 956 -- TODO: Remove debugging
938 -- print(("Loot slot %d: Source count: %d"):format(loot_slot, floor((#sources / 2) + 0.5))) 957 -- print(("Loot slot %d: Source count: %d"):format(loot_slot, floor((#sources / 2) + 0.5)))
939 958
940 -- Odd index is GUID, even is count. 959 -- Odd index is GUID, even is count.
941 for source_index = 1, #sources, 2 do 960 for loot_index = 1, #loot_info, 2 do
942 local source_type, source_id = ParseGUID(sources[source_index]) 961 local source_guid = loot_info[loot_index]
943 local source_count = sources[source_index + 1] 962 local loot_quantity = loot_info[loot_index + 1]
944 local source_key = ("%s:%d"):format(private.UNIT_TYPE_NAMES[source_type + 1], source_id) 963 local source_type, source_id = ParseGUID(source_guid)
945 -- TODO: Remove debugging 964 -- TODO: Remove debugging
946 -- print(("GUID: %s - Type:ID: %s - Amount: %d"):format(sources[source_index], source_key, source_count)) 965 -- local source_key = ("%s:%d"):format(private.UNIT_TYPE_NAMES[source_type + 1], source_id)
947 966 -- print(("GUID: %s - Type:ID: %s - Amount: %d"):format(loot_info[loot_index], source_key, loot_quantity))
948 -- Items return the player as the source, so we need to replace the nil ID with the item's ID (disenchant, milling, etc) 967
949 if not source_id then
950 source_id = action_data.identifier
951 elseif action_data.type == AF.OBJECT then
952 source_id = ("%s:%s"):format(action_data.spell_label, source_id)
953 end
954 local item_id = ItemLinkToID(_G.GetLootSlotLink(loot_slot)) 968 local item_id = ItemLinkToID(_G.GetLootSlotLink(loot_slot))
955 action_data.loot_sources[source_id] = action_data.loot_sources[source_id] or {} 969 action_data.loot_sources[source_guid] = action_data.loot_sources[source_guid] or {}
956 action_data.loot_sources[source_id][item_id] = action_data.loot_sources[source_id][item_id] or 0 + source_count 970 action_data.loot_sources[source_guid][item_id] = action_data.loot_sources[source_guid][item_id] or 0 + loot_quantity
957 end 971 end
958 elseif slot_type == _G.LOOT_SLOT_MONEY then 972 elseif slot_type == _G.LOOT_SLOT_MONEY then
959 table.insert(action_data.loot_list, ("money:%d"):format(_toCopper(item_text))) 973 table.insert(action_data.loot_list, ("money:%d"):format(_toCopper(item_text)))
960 elseif slot_type == _G.LOOT_SLOT_CURRENCY then 974 elseif slot_type == _G.LOOT_SLOT_CURRENCY then
961 table.insert(action_data.loot_list, ("currency:%d:%s"):format(quantity, icon_texture:match("[^\\]+$"):lower())) 975 table.insert(action_data.loot_list, ("currency:%d:%s"):format(quantity, icon_texture:match("[^\\]+$"):lower()))