comparison Main.lua @ 573:444d15b2091e 8.0.1-8

Added wishy-washy support for Island Expeditions. Data recording methodology is flawed, but there are no other options. Percentages will still be interesting.
author Caleb Atherton <atcaleb@twitch.tv>
date Fri, 05 Oct 2018 20:39:29 -0400
parents 1f472a5452a8
children 89fab01eaba0
comparison
equal deleted inserted replaced
572:3ffe3676eb9d 573:444d15b2091e
120 GOSSIP_CLOSED = "ResumeChatLootRecording", 120 GOSSIP_CLOSED = "ResumeChatLootRecording",
121 GOSSIP_SHOW = true, -- also triggers StopChatLootRecording 121 GOSSIP_SHOW = true, -- also triggers StopChatLootRecording
122 GROUP_ROSTER_UPDATE = true, 122 GROUP_ROSTER_UPDATE = true,
123 GUILDBANKFRAME_CLOSED = "ResumeChatLootRecording", 123 GUILDBANKFRAME_CLOSED = "ResumeChatLootRecording",
124 GUILDBANKFRAME_OPENED = true, -- also triggers StopChatLootRecording 124 GUILDBANKFRAME_OPENED = true, -- also triggers StopChatLootRecording
125 ISLAND_AZERITE_GAIN = true,
126 ISLAND_COMPLETED = true,
125 ITEM_TEXT_BEGIN = true, 127 ITEM_TEXT_BEGIN = true,
126 ITEM_UPGRADE_MASTER_OPENED = true, 128 ITEM_UPGRADE_MASTER_OPENED = true,
127 LOOT_CLOSED = true, 129 LOOT_CLOSED = true,
128 LOOT_OPENED = true, 130 LOOT_OPENED = true,
129 LOOT_SLOT_CLEARED = "HandleBadChatLootData", 131 LOOT_SLOT_CLEARED = "HandleBadChatLootData",
191 local block_chat_loot_data 193 local block_chat_loot_data
192 local chat_loot_data = {} 194 local chat_loot_data = {}
193 local chat_loot_timer_handle 195 local chat_loot_timer_handle
194 local world_quest_timer_handle 196 local world_quest_timer_handle
195 local world_quest_event_timestamp = 0 197 local world_quest_event_timestamp = 0
198 local killed_npcs_in_island = {}
199 local island_difficulty_token
196 local current_target_id 200 local current_target_id
197 local current_loot 201 local current_loot
198 202
199 203
200 -- Data for our current action. Including possible values as a reference. 204 -- Data for our current action. Including possible values as a reference.
582 -- For item containers that open instantly with no spell cast 586 -- For item containers that open instantly with no spell cast
583 if (private.CONTAINER_ITEM_ID_LIST[item_id] == true) and ((not _G.GetNumLootItems()) or (_G.GetNumLootItems() == 0)) then 587 if (private.CONTAINER_ITEM_ID_LIST[item_id] == true) and ((not _G.GetNumLootItems()) or (_G.GetNumLootItems() == 0)) then
584 ClearChatLootData() 588 ClearChatLootData()
585 Debug("HandleItemUse: Beginning chat-based loot timer for item with ID %d.", item_id) 589 Debug("HandleItemUse: Beginning chat-based loot timer for item with ID %d.", item_id)
586 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData) 590 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
591 chat_loot_data.category = AF.ITEM
587 chat_loot_data.identifier = item_id 592 chat_loot_data.identifier = item_id
588 -- For normal item containers 593 -- For normal item containers
589 else 594 else
590 table.wipe(current_action) 595 table.wipe(current_action)
591 current_loot = nil 596 current_loot = nil
825 return 830 return
826 end 831 end
827 Debug("ClearChatLootData: Ending chat-based loot timer.") 832 Debug("ClearChatLootData: Ending chat-based loot timer.")
828 chat_loot_timer_handle:Cancel() 833 chat_loot_timer_handle:Cancel()
829 chat_loot_timer_handle = nil 834 chat_loot_timer_handle = nil
830 835
831 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) and chat_loot_data.loot then 836 -- Slimmed down (and more importantly, separate) versions of GenericLootUpdate, specifically for chat_loot_data
832 -- A slimmed down (and more importantly, separate) version of GenericLootUpdate, specifically for AF.ITEM and chat_loot_data 837 -- First version is for special item containers that 'push' loot without using a loot window
838 if chat_loot_data.identifier and chat_loot_data.loot and chat_loot_data.category == AF.ITEM and private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil then
833 local entry = DBEntry("items", chat_loot_data.identifier) 839 local entry = DBEntry("items", chat_loot_data.identifier)
834 840
835 if entry then 841 if entry then
836 local loot_table = LootTable(entry, "contains") 842 local loot_table = LootTable(entry, "contains")
837 entry["contains_count"] = (entry["contains_count"] or 0) + 1 843 entry["contains_count"] = (entry["contains_count"] or 0) + 1
850 else 856 else
851 table.insert(loot_table, ("%d:%d"):format(loot_token, quantity)) 857 table.insert(loot_table, ("%d:%d"):format(loot_token, quantity))
852 end 858 end
853 end 859 end
854 end 860 end
855 end 861 -- Second version is for Island Expeditions. This code is flawed (by design).
862 elseif chat_loot_data.loot and chat_loot_data.category == AF.NPC then
863 -- Iterate over all NPCs killed in an island expedition (at least by your team)
864 for island_npc_id, kill_count in pairs(killed_npcs_in_island) do
865 local npc = NPCEntry(island_npc_id)
866 if npc then
867 -- Create needed npc fields if required
868 local loot_label = "drops"
869 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
870 encounter_data[loot_label] = encounter_data[loot_label] or {}
871 encounter_data.loot_counts = encounter_data.loot_counts or {}
872 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + kill_count
873
874 for loot_token, quantity in pairs(chat_loot_data.loot) do
875 local label, currency_id = (":"):split(loot_token)
876
877 -- Only support items
878 if (label ~= "currency" or not currency_id) and (loot_token ~= "money") then
879 -- Ignore certain items (dubloon bags)
880 if not private.IGNORED_ISLAND_REWARDS[tonumber(loot_token)] then
881 table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
882 end
883 end
884 end
885 end
886 end
887 end
888 table.wipe(killed_npcs_in_island)
856 table.wipe(chat_loot_data) 889 table.wipe(chat_loot_data)
857 end 890 end
858 891
859 892
860 -- METHODS ------------------------------------------------------------ 893 -- METHODS ------------------------------------------------------------
1279 ClearKilledBossID() 1312 ClearKilledBossID()
1280 ClearLootToastContainerID() 1313 ClearLootToastContainerID()
1281 end 1314 end
1282 1315
1283 1316
1317 -- Store all known killed NPCs during an island in a table
1318 function WDP:ISLAND_AZERITE_GAIN(event_name, amount, gained_by_player, faction_index, gained_by, gained_from)
1319 -- Exit now if GUID is not for an NPC
1320 local unit_type, unit_id = ParseGUID(gained_from)
1321 if not UnitTypeIsNPC(unit_type) then
1322 return
1323 end
1324
1325 -- Otherwise, store the NPC ID in the island kill table (if it already exists there, increment its count by 1)
1326 Debug("%s: Recording killed island NPC with ID #%d.", event_name, unit_id)
1327 if killed_npcs_in_island[unit_id] then
1328 killed_npcs_in_island[unit_id] = killed_npcs_in_island[unit_id] + 1
1329 else
1330 killed_npcs_in_island[unit_id] = 1
1331 end
1332 end
1333
1334
1335 -- Start chat loot timer for NPCs (and store general island information)
1336 function WDP:ISLAND_COMPLETED(event_name)
1337 island_difficulty_token = InstanceDifficultyToken()
1338
1339 Debug("%s: Beginning chat-based loot timer for Island Expedition rewards.", event_name, item_id)
1340 chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
1341 chat_loot_data.category = AF.NPC
1342 chat_loot_data.identifier = 0
1343 end
1344
1345
1284 function WDP:BLACK_MARKET_ITEM_UPDATE(event_name) 1346 function WDP:BLACK_MARKET_ITEM_UPDATE(event_name)
1285 if not ALLOWED_LOCALES[CLIENT_LOCALE] then 1347 if not ALLOWED_LOCALES[CLIENT_LOCALE] then
1286 return 1348 return
1287 end 1349 end
1288 local num_items = _G.C_BlackMarket.GetNumItems() or 0 1350 local num_items = _G.C_BlackMarket.GetNumItems() or 0
1447 end 1509 end
1448 1510
1449 GenericLootUpdate("items") 1511 GenericLootUpdate("items")
1450 current_loot = nil 1512 current_loot = nil
1451 container_loot_toasting = true -- Do not count further loots until timer expires or another container is opened 1513 container_loot_toasting = true -- Do not count further loots until timer expires or another container is opened
1452 elseif loot_source and chat_loot_timer_handle then 1514 elseif loot_source and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
1453 -- Handle currency loot toasts for chat-based loot (we do this instead of reading currency chat messages because the chat messages are very delayed) 1515 -- Handle currency loot toasts for chat-based loot (we do this instead of reading currency chat messages because the chat messages are very delayed)
1454 if loot_type == "currency" then 1516 if loot_type == "currency" then
1455 local currency_id = CurrencyLinkToID(item_link) 1517 local currency_id = CurrencyLinkToID(item_link)
1456 if currency_id and currency_id ~= 0 then 1518 if currency_id and currency_id ~= 0 then
1457 -- Verify that we're still assigning data to the right items 1519 -- Verify that we're still assigning data to the right items
1458 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then 1520 if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
1459 Debug("%s: Captured currency for chat-based loot recording. %d X %d", event_name, currency_id, quantity) 1521 Debug("%s: Captured currency for chat-based loot recording. %d X %d", event_name, currency_id, quantity)
1460 local currency_token = ("currency:%d"):format(currency_id) 1522 local currency_token = ("currency:%d"):format(currency_id)
1461 chat_loot_data.loot = chat_loot_data.loot or {} 1523 chat_loot_data.loot = chat_loot_data.loot or {}
1462 chat_loot_data.loot[currency_token] = (chat_loot_data.loot[currency_token] or 0) + quantity 1524 chat_loot_data.loot[currency_token] = (chat_loot_data.loot[currency_token] or 0) + quantity
1463 else -- If not, cancel the timer and wipe the loot table early 1525 else -- If not, cancel the timer and wipe the loot table early
1468 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link) 1530 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
1469 end 1531 end
1470 -- Handle money loot toasts for chat-based loot (we do this instead of reading money chat messages because the chat messages are very delayed) 1532 -- Handle money loot toasts for chat-based loot (we do this instead of reading money chat messages because the chat messages are very delayed)
1471 elseif loot_type == "money" then 1533 elseif loot_type == "money" then
1472 -- Verify that we're still assigning data to the right items 1534 -- Verify that we're still assigning data to the right items
1473 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then 1535 if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
1474 Debug("%s: Captured money for chat-based loot recording. money X %d", event_name, quantity) 1536 Debug("%s: Captured money for chat-based loot recording. money X %d", event_name, quantity)
1475 chat_loot_data.loot = chat_loot_data.loot or {} 1537 chat_loot_data.loot = chat_loot_data.loot or {}
1476 chat_loot_data.loot["money"] = (chat_loot_data.loot["money"] or 0) + quantity 1538 chat_loot_data.loot["money"] = (chat_loot_data.loot["money"] or 0) + quantity
1477 else -- If not, cancel the timer and wipe the loot table early 1539 else -- If not, cancel the timer and wipe the loot table early
1478 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name) 1540 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
1538 update_func(currency_id, quantity) 1600 update_func(currency_id, quantity)
1539 end 1601 end
1540 1602
1541 1603
1542 local CHAT_MSG_LOOT_UPDATE_FUNCS = { 1604 local CHAT_MSG_LOOT_UPDATE_FUNCS = {
1605 -- Handle chat loot data from item containers
1543 [AF.ITEM] = function(item_id, quantity) 1606 [AF.ITEM] = function(item_id, quantity)
1544 -- Verify that we're still assigning data to the right items 1607 -- Verify that we're still assigning data to the right items
1545 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then 1608 if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
1546 Debug("CHAT_MSG_LOOT: AF.ITEM %d (%d)", item_id, quantity) 1609 Debug("CHAT_MSG_LOOT: AF.ITEM %d (%d)", item_id, quantity)
1547 chat_loot_data.loot = chat_loot_data.loot or {} 1610 chat_loot_data.loot = chat_loot_data.loot or {}
1549 else -- If not, cancel the timer and wipe the loot table early 1612 else -- If not, cancel the timer and wipe the loot table early
1550 Debug("CHAT_MSG_LOOT: We would have assigned the wrong loot!") 1613 Debug("CHAT_MSG_LOOT: We would have assigned the wrong loot!")
1551 ClearChatLootData() 1614 ClearChatLootData()
1552 end 1615 end
1553 end, 1616 end,
1617 -- Handle chat loot data from island expedition rewards
1554 [AF.NPC] = function(item_id, quantity) 1618 [AF.NPC] = function(item_id, quantity)
1555 Debug("CHAT_MSG_LOOT: AF.NPC %d (%d)", item_id, quantity) 1619 Debug("CHAT_MSG_LOOT: AF.NPC %d (%d)", item_id, quantity)
1620 chat_loot_data.loot = chat_loot_data.loot or {}
1621 chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
1556 end, 1622 end,
1623 -- Handle logging spells for objects
1557 [AF.OBJECT] = function(item_id, quantity) 1624 [AF.OBJECT] = function(item_id, quantity)
1558 Debug("CHAT_MSG_LOOT: AF.OBJECT %d (%d)", item_id, quantity) 1625 Debug("CHAT_MSG_LOOT: AF.OBJECT %d (%d)", item_id, quantity)
1559 -- Check for top level object data 1626 -- Check for top level object data
1560 local object_entry = DBEntry("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id])) 1627 local object_entry = DBEntry("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id]))
1561 local difficulty_token = InstanceDifficultyToken() 1628 local difficulty_token = InstanceDifficultyToken()
1568 table.insert(object_entry[difficulty_token]["opening"], ("%d:%d"):format(item_id, quantity)) 1635 table.insert(object_entry[difficulty_token]["opening"], ("%d:%d"):format(item_id, quantity))
1569 else 1636 else
1570 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]) 1637 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])
1571 end 1638 end
1572 end, 1639 end,
1640 -- Handle fishing loot table population
1573 [AF.ZONE] = function(item_id, quantity) 1641 [AF.ZONE] = function(item_id, quantity)
1574 Debug("CHAT_MSG_LOOT: AF.ZONE %d (%d)", item_id, quantity) 1642 Debug("CHAT_MSG_LOOT: AF.ZONE %d (%d)", item_id, quantity)
1575 InitializeCurrentLoot() 1643 InitializeCurrentLoot()
1576 current_loot.list[1] = ("%d:%d"):format(item_id, quantity) 1644 current_loot.list[1] = ("%d:%d"):format(item_id, quantity)
1577 GenericLootUpdate("zones") 1645 GenericLootUpdate("zones")
1594 end 1662 end
1595 1663
1596 -- Set update category 1664 -- Set update category
1597 if last_timber_spell_id and item_id == ITEM_ID_TIMBER then 1665 if last_timber_spell_id and item_id == ITEM_ID_TIMBER then
1598 category = AF.OBJECT 1666 category = AF.OBJECT
1599 -- Recently changed from ~= "EXTRACT_GAS" because of some occassional bad data, and, as far as I know, no benefit. 1667 -- Changed from ~= "EXTRACT_GAS" because of some occassional bad data, and, as far as I know, no benefit.
1600 elseif current_action.spell_label == "FISHING" then 1668 elseif current_action.spell_label == "FISHING" then
1601 category = AF.ZONE 1669 category = AF.ZONE
1602 elseif raid_boss_id then 1670 elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.NPC then
1603 category = AF.NPC 1671 category = AF.NPC
1604 elseif chat_loot_timer_handle then 1672 elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
1605 category = AF.ITEM 1673 category = AF.ITEM
1606 end 1674 end
1607 1675
1608 -- We still want to record the item's data, even if it doesn't need its drop location recorded 1676 -- We still want to record the item's data, even if it doesn't need its drop location recorded
1609 RecordItemData(item_id, item_link, true) 1677 RecordItemData(item_id, item_link, true)