Mercurial > wow > wowdb-profiler
comparison Main.lua @ 420:bd7a7162cc0f
Added new kill count system for raid encounters based on saved instances/LFRs.
| author | MMOSimca <MMOSimca@gmail.com> | 
|---|---|
| date | Wed, 07 Jan 2015 04:59:49 -0500 | 
| parents | df4820871122 | 
| children | b2cfa966277f | 
   comparison
  equal
  deleted
  inserted
  replaced
| 419:9c964e2d6971 | 420:bd7a7162cc0f | 
|---|---|
| 98 CHAT_MSG_MONSTER_YELL = "RecordQuote", | 98 CHAT_MSG_MONSTER_YELL = "RecordQuote", | 
| 99 CHAT_MSG_SYSTEM = true, | 99 CHAT_MSG_SYSTEM = true, | 
| 100 COMBAT_LOG_EVENT_UNFILTERED = true, | 100 COMBAT_LOG_EVENT_UNFILTERED = true, | 
| 101 COMBAT_TEXT_UPDATE = true, | 101 COMBAT_TEXT_UPDATE = true, | 
| 102 CURSOR_UPDATE = true, | 102 CURSOR_UPDATE = true, | 
| 103 ENCOUNTER_END = true, | |
| 103 FORGE_MASTER_OPENED = true, | 104 FORGE_MASTER_OPENED = true, | 
| 104 GARRISON_MISSION_BONUS_ROLL_COMPLETE = "HandleBadChatLootData", | 105 GARRISON_MISSION_BONUS_ROLL_COMPLETE = "HandleBadChatLootData", | 
| 105 GARRISON_MISSION_COMPLETE_RESPONSE = "HandleBadChatLootData", | 106 GARRISON_MISSION_COMPLETE_RESPONSE = "HandleBadChatLootData", | 
| 106 GOSSIP_SHOW = true, | 107 GOSSIP_SHOW = true, | 
| 107 GROUP_ROSTER_UPDATE = true, | 108 GROUP_ROSTER_UPDATE = true, | 
| 115 MERCHANT_CLOSED = true, | 116 MERCHANT_CLOSED = true, | 
| 116 MERCHANT_SHOW = "UpdateMerchantItems", | 117 MERCHANT_SHOW = "UpdateMerchantItems", | 
| 117 MERCHANT_UPDATE = "UpdateMerchantItems", | 118 MERCHANT_UPDATE = "UpdateMerchantItems", | 
| 118 PET_BAR_UPDATE = true, | 119 PET_BAR_UPDATE = true, | 
| 119 --PET_JOURNAL_LIST_UPDATE = true, | 120 --PET_JOURNAL_LIST_UPDATE = true, | 
| 121 PLAYER_LOGOUT = true, | |
| 120 PLAYER_REGEN_DISABLED = true, | 122 PLAYER_REGEN_DISABLED = true, | 
| 121 PLAYER_REGEN_ENABLED = true, | 123 PLAYER_REGEN_ENABLED = true, | 
| 122 PLAYER_TARGET_CHANGED = true, | 124 PLAYER_TARGET_CHANGED = true, | 
| 123 QUEST_COMPLETE = true, | 125 QUEST_COMPLETE = true, | 
| 124 QUEST_DETAIL = true, | 126 QUEST_DETAIL = true, | 
| 175 local chat_loot_data | 177 local chat_loot_data | 
| 176 local chat_loot_timer_handle | 178 local chat_loot_timer_handle | 
| 177 local current_target_id | 179 local current_target_id | 
| 178 local current_area_id | 180 local current_area_id | 
| 179 local current_loot | 181 local current_loot | 
| 182 local saved_raid_encounter_data | |
| 183 local update_raid_encounter_timer_handle | |
| 184 local saved_difficulty_token | |
| 180 | 185 | 
| 181 | 186 | 
| 182 -- Data for our current action. Including possible values as a reference. | 187 -- Data for our current action. Including possible values as a reference. | 
| 183 local current_action = { | 188 local current_action = { | 
| 184 identifier = nil, | 189 identifier = nil, | 
| 918 table.wipe(chat_loot_data) | 923 table.wipe(chat_loot_data) | 
| 919 end | 924 end | 
| 920 end | 925 end | 
| 921 | 926 | 
| 922 | 927 | 
| 928 -- This wipes a timer as well | |
| 929 local UpdateRaidEncounterInfo | |
| 930 do | |
| 931 local fresh_raid_encounter_data = {} | |
| 932 | |
| 933 function UpdateRaidEncounterInfo() | |
| 934 -- Clear timer info | |
| 935 if update_raid_encounter_timer_handle then | |
| 936 update_raid_encounter_timer_handle:Cancel() | |
| 937 update_raid_encounter_timer_handle = nil | |
| 938 end | |
| 939 table.wipe(fresh_raid_encounter_data) | |
| 940 | |
| 941 -- Collect encounter data for LFR difficulty via RF functions | |
| 942 for i = 1, _G.GetNumRFDungeons() do | |
| 943 local dungeon_ID = _G.GetRFDungeonInfo(i) | |
| 944 fresh_raid_encounter_data[dungeon_ID] = fresh_raid_encounter_data[dungeon_ID] or {} | |
| 945 for j = 1, _G.GetLFGDungeonNumEncounters(dungeon_ID) do | |
| 946 local boss_name, _, is_killed = _G.GetLFGDungeonEncounterInfo(dungeon_ID, j) | |
| 947 fresh_raid_encounter_data[dungeon_ID][boss_name] = is_killed | |
| 948 end | |
| 949 end | |
| 950 | |
| 951 -- Collect encounter data for Normal/Heroic/Mythic difficulty via saved instance functions | |
| 952 for i = 1, _G.GetNumSavedInstances() do | |
| 953 local _, dungeon_ID, _, _, _, _, _, _, _, _, num_encounters = _G.GetSavedInstanceInfo(i) | |
| 954 fresh_raid_encounter_data[dungeon_ID] = fresh_raid_encounter_data[dungeon_ID] or {} | |
| 955 for j = 1, num_encounters do | |
| 956 local boss_name, _, is_killed = _G.GetSavedInstanceEncounterInfo(i, j) | |
| 957 fresh_raid_encounter_data[dungeon_ID][boss_name] = is_killed | |
| 958 end | |
| 959 end | |
| 960 | |
| 961 Debug("UpdateRaidEncounterInfo: Collected fresh raid encounter data.") | |
| 962 if saved_raid_encounter_data then | |
| 963 -- Compare old data vs new table to find changes | |
| 964 for dungeon_ID, sub_table in next, saved_raid_encounter_data do | |
| 965 for boss_name, is_killed in next, saved_raid_encounter_data[dungeon_ID] do | |
| 966 if private.RAID_ENCOUNTER_NAME_TO_NPC_ID_MAP[boss_name] and saved_raid_encounter_data[dungeon_ID][boss_name] == false and fresh_raid_encounter_data[dungeon_ID] and fresh_raid_encounter_data[dungeon_ID][boss_name] == true then | |
| 967 Debug("UpdateRaidEncounterInfo: Incrementing kill count for boss %s with ID %d.", boss_name, private.RAID_ENCOUNTER_NAME_TO_NPC_ID_MAP[boss_name]) | |
| 968 -- Increment kill count for NPC IDs with detected changes | |
| 969 local npc = NPCEntry(private.RAID_ENCOUNTER_NAME_TO_NPC_ID_MAP[boss_name]) | |
| 970 if npc then | |
| 971 local encounter_data = npc:EncounterData(saved_difficulty_token) | |
| 972 encounter_data["drops"] = encounter_data["drops"] or {} | |
| 973 encounter_data.loot_counts = encounter_data.loot_counts or {} | |
| 974 encounter_data.loot_counts["drops"] = (encounter_data.loot_counts["drops"] or 0) + 1 | |
| 975 end | |
| 976 end | |
| 977 end | |
| 978 end | |
| 979 end | |
| 980 | |
| 981 -- Assign new table over old one | |
| 982 saved_raid_encounter_data = fresh_raid_encounter_data | |
| 983 saved_difficulty_token = nil | |
| 984 end | |
| 985 end | |
| 986 | |
| 987 | |
| 923 -- METHODS ------------------------------------------------------------ | 988 -- METHODS ------------------------------------------------------------ | 
| 924 | 989 | 
| 925 function WDP:OnInitialize() | 990 function WDP:OnInitialize() | 
| 926 local db = LibStub("AceDB-3.0"):New("WoWDBProfilerData", DATABASE_DEFAULTS, "Default") | 991 local db = LibStub("AceDB-3.0"):New("WoWDBProfilerData", DATABASE_DEFAULTS, "Default") | 
| 927 private.db = db | 992 private.db = db | 
| 987 end, 100000) | 1052 end, 100000) | 
| 988 target_location_timer_handle = C_Timer.NewTicker(0.5, function() | 1053 target_location_timer_handle = C_Timer.NewTicker(0.5, function() | 
| 989 target_location_timer_handle._remainingIterations = 100000 | 1054 target_location_timer_handle._remainingIterations = 100000 | 
| 990 WDP:UpdateTargetLocation() | 1055 WDP:UpdateTargetLocation() | 
| 991 end, 100000) | 1056 end, 100000) | 
| 1057 | |
| 1058 if ALLOWED_LOCALES[CLIENT_LOCALE] then | |
| 1059 update_raid_encounter_timer_handle = C_Timer.NewTimer(10, UpdateRaidEncounterInfo) | |
| 1060 end | |
| 992 | 1061 | 
| 993 _G.hooksecurefunc("UseContainerItem", function(bag_index, slot_index, target_unit) | 1062 _G.hooksecurefunc("UseContainerItem", function(bag_index, slot_index, target_unit) | 
| 994 if target_unit then | 1063 if target_unit then | 
| 995 return | 1064 return | 
| 996 end | 1065 end | 
| 1285 function WDP:HandleBadChatLootData(...) | 1354 function WDP:HandleBadChatLootData(...) | 
| 1286 ClearChatLootData() | 1355 ClearChatLootData() | 
| 1287 end | 1356 end | 
| 1288 | 1357 | 
| 1289 | 1358 | 
| 1359 -- EVENT HANDLERS ----------------------------------------------------- | |
| 1360 | |
| 1361 function WDP:ENCOUNTER_END(event_name) | |
| 1362 local loot_method = _G.GetLootMethod() | |
| 1363 -- This will only work for english clients due to questionable API design choices | |
| 1364 -- Currently only testing this method of kill count recording for personal loot. | |
| 1365 -- Master looting has too many edge cases, such as chest objects and multiple NPCs with split loot. | |
| 1366 if loot_method ~= "personalloot" or not ALLOWED_LOCALES[CLIENT_LOCALE] then | |
| 1367 return | |
| 1368 end | |
| 1369 | |
| 1370 saved_difficulty_token = InstanceDifficultyToken() | |
| 1371 update_raid_encounter_timer_handle = C_Timer.NewTimer(30, UpdateRaidEncounterInfo) | |
| 1372 end | |
| 1373 | |
| 1374 | |
| 1375 function WDP:PLAYER_LOGOUT(event_name) | |
| 1376 if update_raid_encounter_timer_handle then | |
| 1377 UpdateRaidEncounterInfo() | |
| 1378 end | |
| 1379 end | |
| 1380 | |
| 1290 -- 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. | 1381 -- 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. | 
| 1291 function WDP:BONUS_ROLL_RESULT(event_name) | 1382 function WDP:BONUS_ROLL_RESULT(event_name) | 
| 1292 Debug("%s: Bonus roll detected; stopping loot recording for this boss to avoid recording bonus loot.", event_name) | 1383 Debug("%s: Bonus roll detected; stopping loot recording for this boss to avoid recording bonus loot.", event_name) | 
| 1293 ClearKilledBossID() | 1384 ClearKilledBossID() | 
| 1294 ClearLootToastContainerID() | 1385 ClearLootToastContainerID() | 
| 1382 end | 1473 end | 
| 1383 else | 1474 else | 
| 1384 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link) | 1475 Debug("%s: Currency texture is nil, from currency link %s", event_name, item_link) | 
| 1385 end | 1476 end | 
| 1386 elseif raid_boss_id then | 1477 elseif raid_boss_id then | 
| 1478 local loot_method = _G.GetLootMethod() | |
| 1387 -- Slightly messy hack to workaround duplicate world bosses | 1479 -- Slightly messy hack to workaround duplicate world bosses | 
| 1388 local upper_limit = 0 | 1480 local upper_limit = 0 | 
| 1389 if DUPLICATE_WORLD_BOSS_IDS[raid_boss_id] then | 1481 if DUPLICATE_WORLD_BOSS_IDS[raid_boss_id] then | 
| 1390 upper_limit = #DUPLICATE_WORLD_BOSS_IDS[raid_boss_id] | 1482 upper_limit = #DUPLICATE_WORLD_BOSS_IDS[raid_boss_id] | 
| 1391 end | 1483 end | 
| 1426 return | 1518 return | 
| 1427 end | 1519 end | 
| 1428 end | 1520 end | 
| 1429 | 1521 | 
| 1430 if not boss_loot_toasting[temp_npc_id] then | 1522 if not boss_loot_toasting[temp_npc_id] then | 
| 1431 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1 | 1523 -- In some situations, we will increment kill count by watching what the player is saved to | 
| 1524 if not update_raid_encounter_timer_handle or not private.RAID_ENCOUNTER_NPC_ID_LIST[temp_npc_id] or loot_method ~= "personalloot" then | |
| 1525 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1 | |
| 1526 else | |
| 1527 Debug("%s: Skipping incrementing kill count for NPC ID %d.", event_name, temp_npc_id) | |
| 1528 end | |
| 1432 boss_loot_toasting[temp_npc_id] = true -- Do not count further loots until timer expires or another boss is killed | 1529 boss_loot_toasting[temp_npc_id] = true -- Do not count further loots until timer expires or another boss is killed | 
| 1433 end | 1530 end | 
| 1434 end | 1531 end | 
| 1435 end | 1532 end | 
| 1436 elseif loot_toast_container_id then | 1533 elseif loot_toast_container_id then | 
| 2004 local LOOT_OPENED_UPDATE_FUNCS = { | 2101 local LOOT_OPENED_UPDATE_FUNCS = { | 
| 2005 [AF.ITEM] = function() | 2102 [AF.ITEM] = function() | 
| 2006 GenericLootUpdate("items") | 2103 GenericLootUpdate("items") | 
| 2007 end, | 2104 end, | 
| 2008 [AF.NPC] = function() | 2105 [AF.NPC] = function() | 
| 2106 local loot_method = _G.GetLootMethod() | |
| 2009 local difficulty_token = InstanceDifficultyToken() | 2107 local difficulty_token = InstanceDifficultyToken() | 
| 2010 local loot_label = current_loot.label | 2108 local loot_label = current_loot.label | 
| 2011 local source_list = {} | 2109 local source_list = {} | 
| 2012 | 2110 | 
| 2013 for source_guid, loot_data in pairs(current_loot.sources) do | 2111 for source_guid, loot_data in pairs(current_loot.sources) do | 
| 2018 local encounter_data = npc:EncounterData(difficulty_token) | 2116 local encounter_data = npc:EncounterData(difficulty_token) | 
| 2019 encounter_data[loot_label] = encounter_data[loot_label] or {} | 2117 encounter_data[loot_label] = encounter_data[loot_label] or {} | 
| 2020 | 2118 | 
| 2021 if not source_list[source_guid] then | 2119 if not source_list[source_guid] then | 
| 2022 encounter_data.loot_counts = encounter_data.loot_counts or {} | 2120 encounter_data.loot_counts = encounter_data.loot_counts or {} | 
| 2023 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1 | 2121 -- In some situations, we will increment kill count by watching what the player is saved to | 
| 2122 if not update_raid_encounter_timer_handle or not private.RAID_ENCOUNTER_NPC_ID_LIST[source_id] or loot_method ~= "personalloot" then | |
| 2123 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1 | |
| 2124 else | |
| 2125 | |
| 2126 end | |
| 2024 source_list[source_guid] = true | 2127 source_list[source_guid] = true | 
| 2025 end | 2128 end | 
| 2026 | 2129 | 
| 2027 for loot_token, quantity in pairs(loot_data) do | 2130 for loot_token, quantity in pairs(loot_data) do | 
| 2028 local loot_type, currency_texture = (":"):split(loot_token) | 2131 local loot_type, currency_texture = (":"):split(loot_token) | 
