| 
jcallahan@246
 | 
     1 -- LUA API ------------------------------------------------------------
 | 
| 
jcallahan@246
 | 
     2 
 | 
| 
jcallahan@0
 | 
     3 local _G = getfenv(0)
 | 
| 
jcallahan@0
 | 
     4 
 | 
| 
jcallahan@0
 | 
     5 local pairs = _G.pairs
 | 
| 
jcallahan@312
 | 
     6 local tostring = _G.tostring
 | 
| 
jcallahan@1
 | 
     7 local tonumber = _G.tonumber
 | 
| 
jcallahan@1
 | 
     8 
 | 
| 
jcallahan@1
 | 
     9 local bit = _G.bit
 | 
| 
jcallahan@1
 | 
    10 local math = _G.math
 | 
| 
jcallahan@1
 | 
    11 local table = _G.table
 | 
| 
jcallahan@1
 | 
    12 
 | 
| 
jcallahan@334
 | 
    13 local next = _G.next
 | 
| 
jcallahan@78
 | 
    14 local select = _G.select
 | 
| 
mmosimca@485
 | 
    15 local type = _G.type
 | 
| 
jcallahan@306
 | 
    16 local unpack = _G.unpack
 | 
| 
jcallahan@78
 | 
    17 
 | 
| 
MMOSimca@383
 | 
    18 local C_Timer = _G.C_Timer
 | 
| 
MMOSimca@581
 | 
    19 local C_Spell = _G.C_Spell
 | 
| 
mmosimca@496
 | 
    20 local GetCurrencyInfo = _G.GetCurrencyInfo
 | 
| 
MMOSimca@383
 | 
    21 
 | 
| 
MMOSimca@583
 | 
    22 local ICL = InCombatLockdown
 | 
| 
MMOSimca@583
 | 
    23 local III = IsInInstance
 | 
| 
MMOSimca@583
 | 
    24 
 | 
| 
jcallahan@0
 | 
    25 
 | 
| 
jcallahan@246
 | 
    26 -- ADDON NAMESPACE ----------------------------------------------------
 | 
| 
jcallahan@246
 | 
    27 
 | 
| 
jcallahan@0
 | 
    28 local ADDON_NAME, private = ...
 | 
| 
jcallahan@0
 | 
    29 
 | 
| 
jcallahan@0
 | 
    30 local LibStub = _G.LibStub
 | 
| 
MMOSimca@383
 | 
    31 local WDP = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceConsole-3.0", "AceEvent-3.0")
 | 
| 
jcallahan@0
 | 
    32 
 | 
| 
jcallahan@48
 | 
    33 local deformat = LibStub("LibDeformat-3.0")
 | 
| 
atcaleb@558
 | 
    34 local HereBeDragons = LibStub("HereBeDragons-2.0")
 | 
| 
jcallahan@48
 | 
    35 
 | 
| 
jcallahan@4
 | 
    36 local DatamineTT = _G.CreateFrame("GameTooltip", "WDPDatamineTT", _G.UIParent, "GameTooltipTemplate")
 | 
| 
jcallahan@5
 | 
    37 DatamineTT:SetOwner(_G.WorldFrame, "ANCHOR_NONE")
 | 
| 
jcallahan@5
 | 
    38 
 | 
| 
jcallahan@0
 | 
    39 
 | 
| 
atcaleb@566
 | 
    40 -- SIMPLE CONSTANTS ----------------------------------------------------------
 | 
| 
jcallahan@246
 | 
    41 
 | 
| 
jcallahan@246
 | 
    42 local AF = private.ACTION_TYPE_FLAGS
 | 
| 
jcallahan@246
 | 
    43 local CLIENT_LOCALE = _G.GetLocale()
 | 
| 
atcaleb@565
 | 
    44 local DB_VERSION = 19
 | 
| 
MMOSimca@346
 | 
    45 local DEBUGGING = false
 | 
| 
jcallahan@156
 | 
    46 local EVENT_DEBUG = false
 | 
| 
jcallahan@322
 | 
    47 
 | 
| 
mmosimca@485
 | 
    48 -- Timer durations in seconds
 | 
| 
mmosimca@485
 | 
    49 local DELAY_PROCESS_ITEMS = 30
 | 
| 
atcaleb@566
 | 
    50 local DELAY_PROCESS_WORLD_QUESTS = 90
 | 
| 
mmosimca@485
 | 
    51 local DELAY_UPDATE_TARGET_LOCATION = 0.5
 | 
| 
mmosimca@485
 | 
    52 
 | 
| 
MMOSimca@405
 | 
    53 local ITEM_ID_TIMBER = 114781
 | 
| 
MMOSimca@405
 | 
    54 
 | 
| 
MMOSimca@581
 | 
    55 local ENUM_LOOTSLOTTYPE_CURRENCY = _G.Enum.LootSlotType.Currency
 | 
| 
MMOSimca@581
 | 
    56 local ENUM_LOOTSLOTTYPE_ITEM = _G.Enum.LootSlotType.Item
 | 
| 
MMOSimca@581
 | 
    57 local ENUM_LOOTSLOTTYPE_MONEY = _G.Enum.LootSlotType.Money
 | 
| 
mmosimca@520
 | 
    58 
 | 
| 
MMOSimca@539
 | 
    59 --local LOOT_SOURCE_ID_UNKNOWN = 1 -- Technically unused right now, but has future use potential
 | 
| 
MMOSimca@539
 | 
    60 --local LOOT_SOURCE_ID_REDUNDANT = 3 -- Technically unused right now, but has future use potential
 | 
| 
MMOSimca@422
 | 
    61 local LOOT_SOURCE_ID_GARRISON_CACHE = 10
 | 
| 
MMOSimca@422
 | 
    62 
 | 
| 
jcallahan@246
 | 
    63 local OBJECT_ID_ANVIL = 192628
 | 
| 
jcallahan@322
 | 
    64 local OBJECT_ID_FISHING_BOBBER = 35591
 | 
| 
jcallahan@246
 | 
    65 local OBJECT_ID_FORGE = 1685
 | 
| 
jcallahan@322
 | 
    66 
 | 
| 
MMOSimca@454
 | 
    67 local PLAYER_CLASS, PLAYER_CLASS_ID = _G.select(2, _G.UnitClass("player"))
 | 
| 
jcallahan@246
 | 
    68 local PLAYER_FACTION = _G.UnitFactionGroup("player")
 | 
| 
jcallahan@300
 | 
    69 local PLAYER_GUID
 | 
| 
mmosimca@485
 | 
    70 local PLAYER_LEVEL = _G.UnitLevel("player")
 | 
| 
jcallahan@246
 | 
    71 local PLAYER_NAME = _G.UnitName("player")
 | 
| 
jcallahan@246
 | 
    72 local PLAYER_RACE = _G.select(2, _G.UnitRace("player"))
 | 
| 
jcallahan@246
 | 
    73 
 | 
| 
mmosimca@520
 | 
    74 local SPELL_ID_UPDATE_INTERACTIONS = 161006
 | 
| 
MMOSimca@377
 | 
    75 
 | 
| 
atcaleb@566
 | 
    76 local UI_MAP_COSMIC = 946
 | 
| 
atcaleb@566
 | 
    77 
 | 
| 
jcallahan@246
 | 
    78 local ALLOWED_LOCALES = {
 | 
| 
jcallahan@246
 | 
    79     enUS = true,
 | 
| 
jcallahan@246
 | 
    80     enGB = true,
 | 
| 
MMOSimca@336
 | 
    81     enTW = true,
 | 
| 
MMOSimca@336
 | 
    82     enCN = true,
 | 
| 
jcallahan@246
 | 
    83 }
 | 
| 
jcallahan@157
 | 
    84 
 | 
| 
jcallahan@0
 | 
    85 local DATABASE_DEFAULTS = {
 | 
| 
jcallahan@128
 | 
    86     char = {},
 | 
| 
jcallahan@0
 | 
    87     global = {
 | 
| 
jcallahan@270
 | 
    88         config = {
 | 
| 
jcallahan@270
 | 
    89             minimap_icon = {
 | 
| 
jcallahan@270
 | 
    90                 hide = true,
 | 
| 
jcallahan@270
 | 
    91             },
 | 
| 
jcallahan@270
 | 
    92         },
 | 
| 
jcallahan@0
 | 
    93         items = {},
 | 
| 
jcallahan@0
 | 
    94         npcs = {},
 | 
| 
jcallahan@0
 | 
    95         objects = {},
 | 
| 
jcallahan@0
 | 
    96         quests = {},
 | 
| 
jcallahan@167
 | 
    97         spells = {},
 | 
| 
MMOSimca@550
 | 
    98         world_quests = {},
 | 
| 
jcallahan@17
 | 
    99         zones = {},
 | 
| 
jcallahan@0
 | 
   100     }
 | 
| 
jcallahan@0
 | 
   101 }
 | 
| 
jcallahan@0
 | 
   102 
 | 
| 
jcallahan@1
 | 
   103 local EVENT_MAPPING = {
 | 
| 
MMOSimca@436
 | 
   104     AUCTION_HOUSE_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   105     AUCTION_HOUSE_SHOW = true, -- also triggers StopChatLootRecording
 | 
| 
MMOSimca@436
 | 
   106     BANKFRAME_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   107     BANKFRAME_OPENED = true, -- also triggers StopChatLootRecording
 | 
| 
jcallahan@90
 | 
   108     BATTLEFIELDS_SHOW = true,
 | 
| 
jcallahan@56
 | 
   109     BLACK_MARKET_ITEM_UPDATE = true,
 | 
| 
MMOSimca@408
 | 
   110     BONUS_ROLL_RESULT = true,
 | 
| 
MMOSimca@388
 | 
   111     CHAT_MSG_CURRENCY = true,
 | 
| 
jcallahan@48
 | 
   112     CHAT_MSG_LOOT = true,
 | 
| 
jcallahan@95
 | 
   113     CHAT_MSG_MONSTER_SAY = "RecordQuote",
 | 
| 
jcallahan@95
 | 
   114     CHAT_MSG_MONSTER_WHISPER = "RecordQuote",
 | 
| 
jcallahan@95
 | 
   115     CHAT_MSG_MONSTER_YELL = "RecordQuote",
 | 
| 
jcallahan@40
 | 
   116     CHAT_MSG_SYSTEM = true,
 | 
| 
MMOSimca@581
 | 
   117     WORLD_CURSOR_TOOLTIP_UPDATE = true,
 | 
| 
MMOSimca@436
 | 
   118     GARRISON_MISSION_NPC_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   119     GARRISON_MISSION_NPC_OPENED = "StopChatLootRecording",
 | 
| 
MMOSimca@450
 | 
   120     GARRISON_SHIPYARD_NPC_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@450
 | 
   121     GARRISON_SHIPYARD_NPC_OPENED = "StopChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   122     GOSSIP_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   123     GOSSIP_SHOW = true, -- also triggers StopChatLootRecording
 | 
| 
jcallahan@290
 | 
   124     GROUP_ROSTER_UPDATE = true,
 | 
| 
MMOSimca@436
 | 
   125     GUILDBANKFRAME_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   126     GUILDBANKFRAME_OPENED = true, -- also triggers StopChatLootRecording
 | 
| 
atcaleb@573
 | 
   127     ISLAND_AZERITE_GAIN = true,
 | 
| 
atcaleb@573
 | 
   128     ISLAND_COMPLETED = true,
 | 
| 
jcallahan@42
 | 
   129     ITEM_TEXT_BEGIN = true,
 | 
| 
jcallahan@124
 | 
   130     LOOT_CLOSED = true,
 | 
| 
MMOSimca@343
 | 
   131     LOOT_OPENED = true,
 | 
| 
MMOSimca@412
 | 
   132     LOOT_SLOT_CLEARED = "HandleBadChatLootData",
 | 
| 
MMOSimca@436
 | 
   133     MAIL_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@436
 | 
   134     MAIL_SHOW = true, -- also triggers StopChatLootRecording
 | 
| 
MMOSimca@436
 | 
   135     MERCHANT_CLOSED = true, -- also triggers ResumeChatLootRecording
 | 
| 
MMOSimca@436
 | 
   136     MERCHANT_SHOW = "UpdateMerchantItems", -- also triggers StopChatLootRecording
 | 
| 
jcallahan@61
 | 
   137     MERCHANT_UPDATE = "UpdateMerchantItems",
 | 
| 
jcallahan@25
 | 
   138     PET_BAR_UPDATE = true,
 | 
| 
MMOSimca@368
 | 
   139     --PET_JOURNAL_LIST_UPDATE = true,
 | 
| 
jcallahan@156
 | 
   140     PLAYER_REGEN_DISABLED = true,
 | 
| 
jcallahan@156
 | 
   141     PLAYER_REGEN_ENABLED = true,
 | 
| 
jcallahan@2
 | 
   142     PLAYER_TARGET_CHANGED = true,
 | 
| 
jcallahan@9
 | 
   143     QUEST_COMPLETE = true,
 | 
| 
jcallahan@9
 | 
   144     QUEST_DETAIL = true,
 | 
| 
jcallahan@9
 | 
   145     QUEST_LOG_UPDATE = true,
 | 
| 
jcallahan@97
 | 
   146     QUEST_PROGRESS = true,
 | 
| 
jcallahan@178
 | 
   147     SHOW_LOOT_TOAST = true,
 | 
| 
jcallahan@306
 | 
   148     SPELL_CONFIRMATION_PROMPT = true,
 | 
| 
jcallahan@88
 | 
   149     TAXIMAP_OPENED = true,
 | 
| 
MMOSimca@437
 | 
   150     TRADE_CLOSED = "ResumeChatLootRecording",
 | 
| 
MMOSimca@437
 | 
   151     TRADE_SHOW = "StopChatLootRecording",
 | 
| 
MMOSimca@581
 | 
   152     --TRADE_SKILL_SHOW = true,
 | 
| 
MMOSimca@581
 | 
   153     --TRAINER_CLOSED = true,
 | 
| 
MMOSimca@581
 | 
   154     --TRAINER_SHOW = true,
 | 
| 
jcallahan@246
 | 
   155     UNIT_PET = true,
 | 
| 
jcallahan@4
 | 
   156     UNIT_QUEST_LOG_CHANGED = true,
 | 
| 
MMOSimca@581
 | 
   157     PLAYER_INTERACTION_MANAGER_FRAME_SHOW = true,
 | 
| 
jcallahan@0
 | 
   158 }
 | 
| 
jcallahan@0
 | 
   159 
 | 
| 
jcallahan@4
 | 
   160 
 | 
| 
jcallahan@246
 | 
   161 -- VARIABLES ----------------------------------------------------------
 | 
| 
jcallahan@246
 | 
   162 
 | 
| 
jcallahan@92
 | 
   163 local anvil_spell_ids = {}
 | 
| 
jcallahan@92
 | 
   164 local currently_drunk
 | 
| 
jcallahan@128
 | 
   165 local char_db
 | 
| 
jcallahan@128
 | 
   166 local global_db
 | 
| 
jcallahan@299
 | 
   167 local group_member_guids = {}
 | 
| 
jcallahan@246
 | 
   168 local group_owner_guids_to_pet_guids = {}
 | 
| 
jcallahan@246
 | 
   169 local group_pet_guids = {}
 | 
| 
jcallahan@299
 | 
   170 local in_instance
 | 
| 
jcallahan@187
 | 
   171 local item_process_timer_handle
 | 
| 
jcallahan@92
 | 
   172 local faction_standings = {}
 | 
| 
jcallahan@92
 | 
   173 local forge_spell_ids = {}
 | 
| 
jcallahan@95
 | 
   174 local languages_known = {}
 | 
| 
jcallahan@317
 | 
   175 local boss_loot_toasting = {}
 | 
| 
MMOSimca@387
 | 
   176 local container_loot_toasting
 | 
| 
MMOSimca@387
 | 
   177 local loot_toast_container_id
 | 
| 
MMOSimca@387
 | 
   178 local raid_boss_id
 | 
| 
jcallahan@306
 | 
   179 local loot_toast_container_timer_handle
 | 
| 
jcallahan@307
 | 
   180 local loot_toast_data
 | 
| 
jcallahan@307
 | 
   181 local loot_toast_data_timer_handle
 | 
| 
jcallahan@95
 | 
   182 local name_to_id_map = {}
 | 
| 
jcallahan@306
 | 
   183 local killed_boss_id_timer_handle
 | 
| 
jcallahan@177
 | 
   184 local killed_npc_id
 | 
| 
jcallahan@2
 | 
   185 local target_location_timer_handle
 | 
| 
MMOSimca@345
 | 
   186 local last_timber_spell_id
 | 
| 
MMOSimca@355
 | 
   187 local last_garrison_cache_object_id
 | 
| 
MMOSimca@436
 | 
   188 local block_chat_loot_data
 | 
| 
MMOSimca@435
 | 
   189 local chat_loot_data = {}
 | 
| 
MMOSimca@347
 | 
   190 local chat_loot_timer_handle
 | 
| 
mmosimca@485
 | 
   191 local world_quest_timer_handle
 | 
| 
mmosimca@485
 | 
   192 local world_quest_event_timestamp = 0
 | 
| 
atcaleb@573
 | 
   193 local killed_npcs_in_island = {}
 | 
| 
atcaleb@573
 | 
   194 local island_difficulty_token
 | 
| 
jcallahan@86
 | 
   195 local current_target_id
 | 
| 
jcallahan@131
 | 
   196 local current_loot
 | 
| 
jcallahan@1
 | 
   197 
 | 
| 
jcallahan@312
 | 
   198 
 | 
| 
jcallahan@121
 | 
   199 -- Data for our current action. Including possible values as a reference.
 | 
| 
jcallahan@122
 | 
   200 local current_action = {
 | 
| 
jcallahan@121
 | 
   201     identifier = nil,
 | 
| 
jcallahan@121
 | 
   202     loot_label = nil,
 | 
| 
jcallahan@121
 | 
   203     loot_list = nil,
 | 
| 
jcallahan@121
 | 
   204     loot_sources = nil,
 | 
| 
jcallahan@121
 | 
   205     map_level = nil,
 | 
| 
jcallahan@121
 | 
   206     spell_label = nil,
 | 
| 
jcallahan@123
 | 
   207     target_type = nil,
 | 
| 
jcallahan@121
 | 
   208     x = nil,
 | 
| 
jcallahan@121
 | 
   209     y = nil,
 | 
| 
jcallahan@121
 | 
   210     zone_data = nil,
 | 
| 
jcallahan@121
 | 
   211 }
 | 
| 
jcallahan@92
 | 
   212 
 | 
| 
jcallahan@246
 | 
   213 
 | 
| 
MMOSimca@393
 | 
   214 -- Timer prototypes
 | 
| 
MMOSimca@393
 | 
   215 local ClearKilledNPC, ClearKilledBossID, ClearLootToastContainerID, ClearLootToastData, ClearChatLootData
 | 
| 
MMOSimca@393
 | 
   216 
 | 
| 
MMOSimca@393
 | 
   217 
 | 
| 
jcallahan@246
 | 
   218 -- HELPERS ------------------------------------------------------------
 | 
| 
jcallahan@246
 | 
   219 
 | 
| 
jcallahan@245
 | 
   220 local function Debug(message, ...)
 | 
| 
MMOSimca@350
 | 
   221     if not DEBUGGING or not message then
 | 
| 
jcallahan@151
 | 
   222         return
 | 
| 
jcallahan@151
 | 
   223     end
 | 
| 
catherton@465
 | 
   224 
 | 
| 
MMOSimca@350
 | 
   225     if ... then
 | 
| 
MMOSimca@350
 | 
   226         local args = { ... }
 | 
| 
MMOSimca@350
 | 
   227 
 | 
| 
MMOSimca@350
 | 
   228         for index = 1, #args do
 | 
| 
MMOSimca@377
 | 
   229             args[index] = tostring(args[index])
 | 
| 
jcallahan@306
 | 
   230         end
 | 
| 
MMOSimca@350
 | 
   231         _G.print(message:format(unpack(args)))
 | 
| 
MMOSimca@350
 | 
   232     else
 | 
| 
MMOSimca@350
 | 
   233         _G.print(message)
 | 
| 
jcallahan@306
 | 
   234     end
 | 
| 
jcallahan@151
 | 
   235 end
 | 
| 
jcallahan@151
 | 
   236 
 | 
| 
jcallahan@151
 | 
   237 
 | 
| 
MMOSimca@393
 | 
   238 local function InitializeCurrentLoot()
 | 
| 
MMOSimca@393
 | 
   239     current_loot = {
 | 
| 
MMOSimca@393
 | 
   240         list = {},
 | 
| 
MMOSimca@393
 | 
   241         sources = {},
 | 
| 
MMOSimca@393
 | 
   242         identifier = current_action.identifier,
 | 
| 
MMOSimca@393
 | 
   243         label = current_action.loot_label or "drops",
 | 
| 
MMOSimca@393
 | 
   244         map_level = current_action.map_level,
 | 
| 
MMOSimca@393
 | 
   245         object_name = current_action.object_name,
 | 
| 
MMOSimca@393
 | 
   246         spell_label = current_action.spell_label,
 | 
| 
MMOSimca@393
 | 
   247         target_type = current_action.target_type,
 | 
| 
MMOSimca@393
 | 
   248         x = current_action.x,
 | 
| 
MMOSimca@393
 | 
   249         y = current_action.y,
 | 
| 
MMOSimca@393
 | 
   250         zone_data = current_action.zone_data,
 | 
| 
MMOSimca@393
 | 
   251     }
 | 
| 
MMOSimca@393
 | 
   252 
 | 
| 
MMOSimca@393
 | 
   253     table.wipe(current_action)
 | 
| 
MMOSimca@393
 | 
   254 end
 | 
| 
MMOSimca@393
 | 
   255 
 | 
| 
MMOSimca@393
 | 
   256 
 | 
| 
jcallahan@169
 | 
   257 local TradeSkillExecutePer
 | 
| 
jcallahan@169
 | 
   258 do
 | 
| 
jcallahan@169
 | 
   259     local header_list = {}
 | 
| 
jcallahan@169
 | 
   260 
 | 
| 
jcallahan@169
 | 
   261     function TradeSkillExecutePer(iter_func)
 | 
| 
jcallahan@169
 | 
   262         if not _G.TradeSkillFrame or not _G.TradeSkillFrame:IsVisible() then
 | 
| 
jcallahan@169
 | 
   263             return
 | 
| 
jcallahan@169
 | 
   264         end
 | 
| 
catherton@465
 | 
   265 
 | 
| 
catherton@479
 | 
   266         local recipes = _G.C_TradeSkillUI.GetAllRecipeIDs()
 | 
| 
catherton@479
 | 
   267 
 | 
| 
catherton@479
 | 
   268         if recipes and (#recipes > 0) then
 | 
| 
catherton@479
 | 
   269             for i = 1, #recipes do
 | 
| 
catherton@479
 | 
   270                 if iter_func(_G.C_TradeSkillUI.GetRecipeInfo(recipes[i]).name, recipes[i]) then
 | 
| 
catherton@465
 | 
   271                     break
 | 
| 
catherton@465
 | 
   272                 end
 | 
| 
catherton@465
 | 
   273             end
 | 
| 
catherton@465
 | 
   274         end
 | 
| 
jcallahan@167
 | 
   275     end
 | 
| 
jcallahan@169
 | 
   276 end -- do-block
 | 
| 
jcallahan@167
 | 
   277 
 | 
| 
jcallahan@167
 | 
   278 
 | 
| 
jcallahan@39
 | 
   279 local ActualCopperCost
 | 
| 
jcallahan@39
 | 
   280 do
 | 
| 
jcallahan@39
 | 
   281     local BARTERING_SPELL_ID = 83964
 | 
| 
jcallahan@39
 | 
   282 
 | 
| 
jcallahan@39
 | 
   283     function ActualCopperCost(copper_cost, rep_standing)
 | 
| 
jcallahan@39
 | 
   284         if not copper_cost or copper_cost == 0 then
 | 
| 
jcallahan@39
 | 
   285             return 0
 | 
| 
jcallahan@39
 | 
   286         end
 | 
| 
jcallahan@39
 | 
   287         local modifier = 1
 | 
| 
jcallahan@39
 | 
   288 
 | 
| 
jcallahan@39
 | 
   289         if _G.IsSpellKnown(BARTERING_SPELL_ID) then
 | 
| 
jcallahan@39
 | 
   290             modifier = modifier - 0.1
 | 
| 
jcallahan@39
 | 
   291         end
 | 
| 
jcallahan@39
 | 
   292 
 | 
| 
jcallahan@39
 | 
   293         if rep_standing then
 | 
| 
jcallahan@39
 | 
   294             if PLAYER_RACE == "Goblin" then
 | 
| 
atcaleb@558
 | 
   295                 modifier = modifier - private.STANDING_DISCOUNTS["EXALTED"]
 | 
| 
atcaleb@558
 | 
   296             elseif private.STANDING_DISCOUNTS[rep_standing] then
 | 
| 
atcaleb@558
 | 
   297                 modifier = modifier - private.STANDING_DISCOUNTS[rep_standing]
 | 
| 
jcallahan@39
 | 
   298             end
 | 
| 
jcallahan@39
 | 
   299         end
 | 
| 
jcallahan@39
 | 
   300         return math.floor(copper_cost / modifier)
 | 
| 
jcallahan@39
 | 
   301     end
 | 
| 
jcallahan@39
 | 
   302 end -- do-block
 | 
| 
jcallahan@39
 | 
   303 
 | 
| 
jcallahan@39
 | 
   304 
 | 
| 
jcallahan@29
 | 
   305 local function InstanceDifficultyToken()
 | 
| 
MMOSimca@440
 | 
   306     -- Sometimes, instance information is returned when not in an instance. This check protects against that.
 | 
| 
MMOSimca@440
 | 
   307     if _G.IsInInstance() then
 | 
| 
MMOSimca@440
 | 
   308         local _, instance_type, instance_difficulty, _, _, _, is_dynamic = _G.GetInstanceInfo()
 | 
| 
MMOSimca@440
 | 
   309 
 | 
| 
MMOSimca@440
 | 
   310         if not instance_type or instance_type == "" then
 | 
| 
MMOSimca@440
 | 
   311             instance_type = "NONE"
 | 
| 
MMOSimca@440
 | 
   312         end
 | 
| 
MMOSimca@440
 | 
   313         return ("%s:%d:%s"):format(instance_type:upper(), instance_difficulty, tostring(is_dynamic))
 | 
| 
jcallahan@59
 | 
   314     end
 | 
| 
MMOSimca@440
 | 
   315     return "NONE:0:false"
 | 
| 
jcallahan@29
 | 
   316 end
 | 
| 
jcallahan@29
 | 
   317 
 | 
| 
jcallahan@29
 | 
   318 
 | 
| 
jcallahan@1
 | 
   319 local function CurrentLocationData()
 | 
| 
mmosimca@488
 | 
   320     local x, y, current_area_id, map_level, map_file, is_micro_dungeon = HereBeDragons:GetPlayerZonePosition(false)
 | 
| 
catherton@468
 | 
   321     local zone_name = _G.GetRealZoneText()
 | 
| 
catherton@465
 | 
   322 
 | 
| 
mmosimca@488
 | 
   323     -- Remove micro-dungeon-ness by translating back to the parent world map (at floor 0) if possible
 | 
| 
mmosimca@488
 | 
   324     if (is_micro_dungeon and x and y and current_area_id and map_level and map_level > 0) then
 | 
| 
mmosimca@488
 | 
   325         x, y = HereBeDragons:TranslateZoneCoordinates(x, y, current_area_id, map_level, current_area_id, 0, false)
 | 
| 
mmosimca@488
 | 
   326         map_level = 0
 | 
| 
mmosimca@488
 | 
   327     end
 | 
| 
mmosimca@488
 | 
   328 
 | 
| 
catherton@465
 | 
   329     -- Put coordinates into expected format (as integers, they don't get a billion decimals output in the SavedVariables)
 | 
| 
catherton@468
 | 
   330     local x_int = nil
 | 
| 
catherton@468
 | 
   331     if (x and type(x) == "number") then
 | 
| 
catherton@468
 | 
   332         x_int = _G.floor(x * 1000)
 | 
| 
mmosimca@485
 | 
   333 
 | 
| 
mmosimca@482
 | 
   334         -- Limit precision to 0.2
 | 
| 
catherton@468
 | 
   335         if x_int % 2 ~= 0 then
 | 
| 
catherton@468
 | 
   336             x_int = x_int + 1
 | 
| 
catherton@468
 | 
   337         end
 | 
| 
mmosimca@485
 | 
   338 
 | 
| 
mmosimca@482
 | 
   339         -- Prevent out of bounds coordinates
 | 
| 
mmosimca@482
 | 
   340         if (x_int < 0 or x_int > 1000) then
 | 
| 
mmosimca@482
 | 
   341             x_int = nil
 | 
| 
mmosimca@482
 | 
   342         end
 | 
| 
jcallahan@145
 | 
   343     end
 | 
| 
catherton@468
 | 
   344     local y_int = nil
 | 
| 
catherton@468
 | 
   345     if (y and type(y) == "number") then
 | 
| 
catherton@468
 | 
   346         y_int = _G.floor(y * 1000)
 | 
| 
mmosimca@485
 | 
   347 
 | 
| 
mmosimca@482
 | 
   348         -- Limit precision to 0.2
 | 
| 
catherton@468
 | 
   349         if y_int % 2 ~= 0 then
 | 
| 
catherton@468
 | 
   350             y_int = y_int + 1
 | 
| 
catherton@468
 | 
   351         end
 | 
| 
mmosimca@485
 | 
   352 
 | 
| 
mmosimca@482
 | 
   353         -- Prevent out of bounds coordinates
 | 
| 
mmosimca@482
 | 
   354         if (y_int < 0 or y_int > 1000) then
 | 
| 
mmosimca@482
 | 
   355             y_int = nil
 | 
| 
mmosimca@482
 | 
   356         end
 | 
| 
jcallahan@1
 | 
   357     end
 | 
| 
jcallahan@1
 | 
   358 
 | 
| 
catherton@468
 | 
   359     return zone_name, current_area_id, x_int, y_int, map_level, InstanceDifficultyToken()
 | 
| 
jcallahan@1
 | 
   360 end
 | 
| 
jcallahan@1
 | 
   361 
 | 
| 
jcallahan@1
 | 
   362 
 | 
| 
MMOSimca@441
 | 
   363 local function DBEntry(data_type, unit_id)
 | 
| 
MMOSimca@441
 | 
   364     if not data_type or not unit_id then
 | 
| 
jcallahan@312
 | 
   365         return
 | 
| 
jcallahan@312
 | 
   366     end
 | 
| 
MMOSimca@441
 | 
   367     local category = global_db[data_type]
 | 
| 
MMOSimca@441
 | 
   368 
 | 
| 
MMOSimca@441
 | 
   369     if not category then
 | 
| 
MMOSimca@441
 | 
   370         category = {}
 | 
| 
MMOSimca@441
 | 
   371         global_db[data_type] = category
 | 
| 
MMOSimca@441
 | 
   372     end
 | 
| 
MMOSimca@441
 | 
   373     local unit = category[unit_id]
 | 
| 
MMOSimca@441
 | 
   374 
 | 
| 
MMOSimca@441
 | 
   375     if not unit then
 | 
| 
MMOSimca@441
 | 
   376         unit = {}
 | 
| 
MMOSimca@441
 | 
   377         category[unit_id] = unit
 | 
| 
MMOSimca@441
 | 
   378     end
 | 
| 
MMOSimca@441
 | 
   379     return unit
 | 
| 
jcallahan@312
 | 
   380 end
 | 
| 
jcallahan@312
 | 
   381 
 | 
| 
MMOSimca@441
 | 
   382 private.DBEntry = DBEntry
 | 
| 
MMOSimca@441
 | 
   383 
 | 
| 
MMOSimca@441
 | 
   384 local NPCEntry
 | 
| 
MMOSimca@441
 | 
   385 do
 | 
| 
MMOSimca@441
 | 
   386     local npc_prototype = {}
 | 
| 
MMOSimca@441
 | 
   387     local npc_meta = {
 | 
| 
MMOSimca@441
 | 
   388         __index = npc_prototype
 | 
| 
MMOSimca@441
 | 
   389     }
 | 
| 
MMOSimca@441
 | 
   390 
 | 
| 
MMOSimca@441
 | 
   391     function NPCEntry(identifier)
 | 
| 
MMOSimca@441
 | 
   392         local npc = DBEntry("npcs", identifier)
 | 
| 
MMOSimca@441
 | 
   393         return npc and _G.setmetatable(npc, npc_meta) or nil
 | 
| 
jcallahan@1
 | 
   394     end
 | 
| 
MMOSimca@441
 | 
   395 
 | 
| 
MMOSimca@441
 | 
   396     function npc_prototype:EncounterData(difficulty_token)
 | 
| 
MMOSimca@441
 | 
   397         self.encounter_data = self.encounter_data or {}
 | 
| 
MMOSimca@441
 | 
   398         self.encounter_data[difficulty_token] = self.encounter_data[difficulty_token] or {}
 | 
| 
MMOSimca@441
 | 
   399         self.encounter_data[difficulty_token].stats = self.encounter_data[difficulty_token].stats or {}
 | 
| 
MMOSimca@441
 | 
   400 
 | 
| 
MMOSimca@441
 | 
   401         return self.encounter_data[difficulty_token]
 | 
| 
MMOSimca@441
 | 
   402     end
 | 
| 
jcallahan@1
 | 
   403 end
 | 
| 
jcallahan@270
 | 
   404 
 | 
| 
jcallahan@4
 | 
   405 
 | 
| 
jcallahan@141
 | 
   406 local UpdateDBEntryLocation
 | 
| 
jcallahan@141
 | 
   407 do
 | 
| 
jcallahan@141
 | 
   408     -- Fishing node coordinate code based on code in GatherMate2 with permission from Kagaro.
 | 
| 
jcallahan@141
 | 
   409     local function FishingCoordinates(x, y, yard_width, yard_height)
 | 
| 
jcallahan@141
 | 
   410         local facing = _G.GetPlayerFacing()
 | 
| 
jcallahan@141
 | 
   411 
 | 
| 
jcallahan@141
 | 
   412         if not facing then
 | 
| 
jcallahan@141
 | 
   413             return x, y
 | 
| 
jcallahan@141
 | 
   414         end
 | 
| 
jcallahan@246
 | 
   415         local rad = facing + math.pi
 | 
| 
jcallahan@141
 | 
   416         return x + math.sin(rad) * 15 / yard_width, y + math.cos(rad) * 15 / yard_height
 | 
| 
jcallahan@10
 | 
   417     end
 | 
| 
jcallahan@10
 | 
   418 
 | 
| 
jcallahan@24
 | 
   419 
 | 
| 
jcallahan@141
 | 
   420     function UpdateDBEntryLocation(entry_type, identifier)
 | 
| 
jcallahan@141
 | 
   421         if not identifier then
 | 
| 
jcallahan@141
 | 
   422             return
 | 
| 
jcallahan@141
 | 
   423         end
 | 
| 
jcallahan@141
 | 
   424         local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
 | 
| 
MMOSimca@328
 | 
   425         if not (zone_name and area_id and x and y and map_level) then
 | 
| 
mmosimca@508
 | 
   426             if not (_G.IsInInstance()) then
 | 
| 
mmosimca@508
 | 
   427                 Debug("UpdateDBEntryLocation: Missing current location data - %s, %s, %s, %s, %s.", tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
 | 
| 
mmosimca@508
 | 
   428             end
 | 
| 
MMOSimca@328
 | 
   429             return
 | 
| 
MMOSimca@328
 | 
   430         end
 | 
| 
jcallahan@141
 | 
   431         local entry = DBEntry(entry_type, identifier)
 | 
| 
jcallahan@141
 | 
   432         entry[difficulty_token] = entry[difficulty_token] or {}
 | 
| 
jcallahan@141
 | 
   433         entry[difficulty_token].locations = entry[difficulty_token].locations or {}
 | 
| 
jcallahan@141
 | 
   434 
 | 
| 
jcallahan@141
 | 
   435         local zone_token = ("%s:%d"):format(zone_name, area_id)
 | 
| 
jcallahan@141
 | 
   436         local zone_data = entry[difficulty_token].locations[zone_token]
 | 
| 
jcallahan@141
 | 
   437 
 | 
| 
jcallahan@141
 | 
   438         if not zone_data then
 | 
| 
jcallahan@141
 | 
   439             zone_data = {}
 | 
| 
jcallahan@141
 | 
   440             entry[difficulty_token].locations[zone_token] = zone_data
 | 
| 
jcallahan@141
 | 
   441         end
 | 
| 
jcallahan@141
 | 
   442 
 | 
| 
jcallahan@141
 | 
   443         -- Special case for Fishing.
 | 
| 
jcallahan@141
 | 
   444         if current_action.spell_label == "FISHING" then
 | 
| 
atcaleb@561
 | 
   445             local _, q_vector = _G.C_Map.GetWorldPosFromMapPos(area_id, _G.CreateVector2D(0,0))
 | 
| 
atcaleb@561
 | 
   446             local _, w_vector = _G.C_Map.GetWorldPosFromMapPos(area_id, _G.CreateVector2D(1,1))
 | 
| 
atcaleb@561
 | 
   447             local yard_width, yard_height = q_vector.y - w_vector.y, q_vector.x - w_vector.x
 | 
| 
jcallahan@141
 | 
   448 
 | 
| 
jcallahan@141
 | 
   449             if yard_width > 0 and yard_height > 0 then
 | 
| 
jcallahan@141
 | 
   450                 x, y = FishingCoordinates(x, y, yard_width, yard_height)
 | 
| 
jcallahan@141
 | 
   451                 current_action.x = x
 | 
| 
jcallahan@141
 | 
   452                 current_action.y = y
 | 
| 
jcallahan@141
 | 
   453             end
 | 
| 
jcallahan@141
 | 
   454         end
 | 
| 
jcallahan@141
 | 
   455         local location_token = ("%d:%d:%d"):format(map_level, x, y)
 | 
| 
jcallahan@141
 | 
   456 
 | 
| 
jcallahan@141
 | 
   457         zone_data[location_token] = zone_data[location_token] or true
 | 
| 
jcallahan@141
 | 
   458         return zone_data
 | 
| 
jcallahan@10
 | 
   459     end
 | 
| 
jcallahan@141
 | 
   460 end -- do-block
 | 
| 
jcallahan@10
 | 
   461 
 | 
| 
jcallahan@10
 | 
   462 
 | 
| 
mmosimca@496
 | 
   463 local function CurrencyLinkToID(currency_link)
 | 
| 
MMOSimca@441
 | 
   464     if not currency_link then
 | 
| 
mmosimca@496
 | 
   465         return nil
 | 
| 
MMOSimca@441
 | 
   466     end
 | 
| 
MMOSimca@540
 | 
   467     return tonumber(tostring(currency_link):match("currency:(%d+)"))
 | 
| 
MMOSimca@441
 | 
   468 end
 | 
| 
MMOSimca@441
 | 
   469 
 | 
| 
MMOSimca@441
 | 
   470 
 | 
| 
MMOSimca@441
 | 
   471 local function ItemLinkToID(item_link)
 | 
| 
MMOSimca@441
 | 
   472     if not item_link then
 | 
| 
MMOSimca@441
 | 
   473         return
 | 
| 
MMOSimca@441
 | 
   474     end
 | 
| 
MMOSimca@441
 | 
   475     return tonumber(tostring(item_link):match("item:(%d+)"))
 | 
| 
MMOSimca@441
 | 
   476 end
 | 
| 
MMOSimca@441
 | 
   477 
 | 
| 
MMOSimca@441
 | 
   478 private.ItemLinkToID = ItemLinkToID
 | 
| 
MMOSimca@441
 | 
   479 
 | 
| 
MMOSimca@441
 | 
   480 local function UnitTypeIsNPC(unit_type)
 | 
| 
MMOSimca@441
 | 
   481     return unit_type == private.UNIT_TYPES.NPC or unit_type == private.UNIT_TYPES.VEHICLE
 | 
| 
MMOSimca@441
 | 
   482 end
 | 
| 
MMOSimca@441
 | 
   483 
 | 
| 
MMOSimca@441
 | 
   484 
 | 
| 
MMOSimca@441
 | 
   485 local ParseGUID
 | 
| 
MMOSimca@441
 | 
   486 do
 | 
| 
MMOSimca@441
 | 
   487     local UNIT_TYPES = private.UNIT_TYPES
 | 
| 
MMOSimca@441
 | 
   488 
 | 
| 
MMOSimca@441
 | 
   489     local NPC_ID_MAPPING = {
 | 
| 
MMOSimca@441
 | 
   490         [62164] = 63191, -- Garalon
 | 
| 
MMOSimca@441
 | 
   491     }
 | 
| 
MMOSimca@441
 | 
   492 
 | 
| 
MMOSimca@441
 | 
   493 
 | 
| 
MMOSimca@441
 | 
   494     local function MatchUnitTypes(unit_type_name)
 | 
| 
MMOSimca@441
 | 
   495         if not unit_type_name then
 | 
| 
MMOSimca@441
 | 
   496             return UNIT_TYPES.UNKNOWN
 | 
| 
MMOSimca@441
 | 
   497         end
 | 
| 
MMOSimca@441
 | 
   498 
 | 
| 
MMOSimca@441
 | 
   499         for def, text in next, UNIT_TYPES do
 | 
| 
MMOSimca@441
 | 
   500             if unit_type_name == text then
 | 
| 
MMOSimca@441
 | 
   501                 return UNIT_TYPES[def]
 | 
| 
MMOSimca@441
 | 
   502             end
 | 
| 
MMOSimca@441
 | 
   503         end
 | 
| 
MMOSimca@441
 | 
   504         return UNIT_TYPES.UNKNOWN
 | 
| 
MMOSimca@441
 | 
   505     end
 | 
| 
MMOSimca@441
 | 
   506 
 | 
| 
MMOSimca@441
 | 
   507 
 | 
| 
MMOSimca@441
 | 
   508     function ParseGUID(guid)
 | 
| 
MMOSimca@441
 | 
   509         if not guid then
 | 
| 
MMOSimca@441
 | 
   510             return
 | 
| 
MMOSimca@441
 | 
   511         end
 | 
| 
MMOSimca@441
 | 
   512 
 | 
| 
MMOSimca@441
 | 
   513         -- We might want to use some of this new information later, but leaving the returns alone for now
 | 
| 
mmosimca@497
 | 
   514         local guid_pieces = { ("-"):split(guid) }
 | 
| 
mmosimca@497
 | 
   515         local unit_type_name, unk_field, server_id, instance_id, zone_uid, unit_id, spawn_uid, player_uid = guid_pieces[1]
 | 
| 
MMOSimca@441
 | 
   516 
 | 
| 
MMOSimca@441
 | 
   517         local unit_type = MatchUnitTypes(unit_type_name)
 | 
| 
mmosimca@518
 | 
   518 
 | 
| 
mmosimca@497
 | 
   519         -- Creatures, GameObjects, Vehicles, and Vignettes
 | 
| 
MMOSimca@441
 | 
   520         if unit_type ~= UNIT_TYPES.PLAYER and unit_type ~= UNIT_TYPES.PET and unit_type ~= UNIT_TYPES.ITEM then
 | 
| 
mmosimca@497
 | 
   521             unk_field, server_id, instance_id, zone_uid, unit_id, spawn_uid = guid_pieces[2], guid_pieces[3], guid_pieces[4], guid_pieces[5], guid_pieces[6], guid_pieces[7]
 | 
| 
mmosimca@497
 | 
   522 
 | 
| 
mmosimca@497
 | 
   523             local id_mapping = NPC_ID_MAPPING[unit_id]
 | 
| 
MMOSimca@441
 | 
   524 
 | 
| 
MMOSimca@441
 | 
   525             if id_mapping and UnitTypeIsNPC(unit_type) then
 | 
| 
mmosimca@497
 | 
   526                 unit_id = id_mapping
 | 
| 
MMOSimca@441
 | 
   527             end
 | 
| 
mmosimca@497
 | 
   528 
 | 
| 
mmosimca@497
 | 
   529         -- Players
 | 
| 
mmosimca@497
 | 
   530         elseif unit_type == UNIT_TYPES.PLAYER then
 | 
| 
mmosimca@497
 | 
   531             server_id, player_uid = guid_pieces[2], guid_pieces[3]
 | 
| 
mmosimca@497
 | 
   532 
 | 
| 
mmosimca@497
 | 
   533         -- Items
 | 
| 
mmosimca@497
 | 
   534         elseif unit_type == UNIT_TYPES.ITEM then
 | 
| 
mmosimca@497
 | 
   535             server_id, unk_field, spawn_uid = guid_pieces[2], guid_pieces[3], guid_pieces[4]
 | 
| 
MMOSimca@441
 | 
   536         end
 | 
| 
mmosimca@518
 | 
   537 
 | 
| 
mmosimca@497
 | 
   538         -- Pets and other (i.e. do nothing)
 | 
| 
mmosimca@497
 | 
   539         return unit_type, unit_id
 | 
| 
MMOSimca@441
 | 
   540     end
 | 
| 
MMOSimca@441
 | 
   541 
 | 
| 
MMOSimca@441
 | 
   542     private.ParseGUID = ParseGUID
 | 
| 
MMOSimca@441
 | 
   543 end -- do-block
 | 
| 
MMOSimca@441
 | 
   544 
 | 
| 
MMOSimca@441
 | 
   545 
 | 
| 
jcallahan@19
 | 
   546 local function HandleItemUse(item_link, bag_index, slot_index)
 | 
| 
jcallahan@19
 | 
   547     if not item_link then
 | 
| 
jcallahan@19
 | 
   548         return
 | 
| 
jcallahan@19
 | 
   549     end
 | 
| 
jcallahan@19
 | 
   550     local item_id = ItemLinkToID(item_link)
 | 
| 
jcallahan@19
 | 
   551 
 | 
| 
jcallahan@19
 | 
   552     if not bag_index or not slot_index then
 | 
| 
jcallahan@19
 | 
   553         for new_bag_index = 0, _G.NUM_BAG_FRAMES do
 | 
| 
MMOSimca@581
 | 
   554             for new_slot_index = 1, _G.C_Container.GetContainerNumSlots(new_bag_index) do
 | 
| 
MMOSimca@581
 | 
   555                 if item_id == ItemLinkToID(_G.C_Container.GetContainerItemLink(new_bag_index, new_slot_index)) then
 | 
| 
jcallahan@19
 | 
   556                     bag_index = new_bag_index
 | 
| 
jcallahan@19
 | 
   557                     slot_index = new_slot_index
 | 
| 
jcallahan@19
 | 
   558                     break
 | 
| 
jcallahan@19
 | 
   559                 end
 | 
| 
jcallahan@19
 | 
   560             end
 | 
| 
jcallahan@19
 | 
   561         end
 | 
| 
jcallahan@19
 | 
   562     end
 | 
| 
jcallahan@19
 | 
   563 
 | 
| 
MMOSimca@410
 | 
   564     local any_loot = false
 | 
| 
MMOSimca@410
 | 
   565 
 | 
| 
MMOSimca@411
 | 
   566     -- Check if Blizzard has marked this item as officially having a chance of containing loot
 | 
| 
MMOSimca@410
 | 
   567     if bag_index and slot_index then
 | 
| 
MMOSimca@581
 | 
   568         local _, _, _, _, _, is_lootable = _G.C_Container.GetContainerItemInfo(bag_index, slot_index)
 | 
| 
MMOSimca@410
 | 
   569         if is_lootable then
 | 
| 
MMOSimca@410
 | 
   570             any_loot = true
 | 
| 
MMOSimca@410
 | 
   571         end
 | 
| 
jcallahan@19
 | 
   572     end
 | 
| 
catherton@465
 | 
   573 
 | 
| 
MMOSimca@410
 | 
   574     -- Check if we've marked this item as one Blizzard provides bad is_lootable data for
 | 
| 
MMOSimca@410
 | 
   575     if private.CONTAINER_ITEM_ID_LIST[item_id] ~= nil then
 | 
| 
MMOSimca@410
 | 
   576         any_loot = true
 | 
| 
jcallahan@19
 | 
   577     end
 | 
| 
MMOSimca@368
 | 
   578 
 | 
| 
MMOSimca@436
 | 
   579     -- Going to block 'chat-loot data' at this level for now because I don't think we actually want normal item containers being recorded in these scenarios either.
 | 
| 
MMOSimca@436
 | 
   580     if any_loot and not block_chat_loot_data then
 | 
| 
MMOSimca@414
 | 
   581         -- For item containers that open instantly with no spell cast
 | 
| 
MMOSimca@410
 | 
   582         if (private.CONTAINER_ITEM_ID_LIST[item_id] == true) and ((not _G.GetNumLootItems()) or (_G.GetNumLootItems() == 0)) then
 | 
| 
MMOSimca@410
 | 
   583             ClearChatLootData()
 | 
| 
MMOSimca@410
 | 
   584             Debug("HandleItemUse: Beginning chat-based loot timer for item with ID %d.", item_id)
 | 
| 
MMOSimca@423
 | 
   585             chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
 | 
| 
atcaleb@573
 | 
   586             chat_loot_data.category = AF.ITEM
 | 
| 
MMOSimca@414
 | 
   587             chat_loot_data.identifier = item_id
 | 
| 
MMOSimca@414
 | 
   588         -- For normal item containers
 | 
| 
MMOSimca@414
 | 
   589         else
 | 
| 
MMOSimca@414
 | 
   590             table.wipe(current_action)
 | 
| 
MMOSimca@414
 | 
   591             current_loot = nil
 | 
| 
MMOSimca@414
 | 
   592             current_action.target_type = AF.ITEM
 | 
| 
MMOSimca@414
 | 
   593             current_action.identifier = item_id
 | 
| 
MMOSimca@414
 | 
   594             current_action.loot_label = "contains"
 | 
| 
MMOSimca@410
 | 
   595         end
 | 
| 
MMOSimca@393
 | 
   596     end
 | 
| 
jcallahan@19
 | 
   597 end
 | 
| 
jcallahan@19
 | 
   598 
 | 
| 
jcallahan@19
 | 
   599 
 | 
| 
jcallahan@39
 | 
   600 local UnitFactionStanding
 | 
| 
jcallahan@32
 | 
   601 local UpdateFactionData
 | 
| 
jcallahan@32
 | 
   602 do
 | 
| 
jcallahan@32
 | 
   603     local MAX_FACTION_INDEX = 1000
 | 
| 
jcallahan@20
 | 
   604 
 | 
| 
jcallahan@32
 | 
   605     local STANDING_NAMES = {
 | 
| 
jcallahan@32
 | 
   606         "HATED",
 | 
| 
jcallahan@32
 | 
   607         "HOSTILE",
 | 
| 
jcallahan@32
 | 
   608         "UNFRIENDLY",
 | 
| 
jcallahan@32
 | 
   609         "NEUTRAL",
 | 
| 
jcallahan@32
 | 
   610         "FRIENDLY",
 | 
| 
jcallahan@32
 | 
   611         "HONORED",
 | 
| 
jcallahan@32
 | 
   612         "REVERED",
 | 
| 
jcallahan@32
 | 
   613         "EXALTED",
 | 
| 
jcallahan@32
 | 
   614     }
 | 
| 
jcallahan@32
 | 
   615 
 | 
| 
jcallahan@39
 | 
   616 
 | 
| 
jcallahan@39
 | 
   617     function UnitFactionStanding(unit)
 | 
| 
jcallahan@135
 | 
   618         local unit_name = _G.UnitName(unit)
 | 
| 
jcallahan@39
 | 
   619         UpdateFactionData()
 | 
| 
jcallahan@39
 | 
   620         DatamineTT:ClearLines()
 | 
| 
jcallahan@39
 | 
   621         DatamineTT:SetUnit(unit)
 | 
| 
jcallahan@39
 | 
   622 
 | 
| 
jcallahan@39
 | 
   623         for line_index = 1, DatamineTT:NumLines() do
 | 
| 
jcallahan@64
 | 
   624             local faction_name = _G["WDPDatamineTTTextLeft" .. line_index]:GetText():trim()
 | 
| 
jcallahan@39
 | 
   625 
 | 
| 
jcallahan@135
 | 
   626             if faction_name and faction_name ~= unit_name and faction_standings[faction_name] then
 | 
| 
jcallahan@39
 | 
   627                 return faction_name, faction_standings[faction_name]
 | 
| 
jcallahan@39
 | 
   628             end
 | 
| 
jcallahan@39
 | 
   629         end
 | 
| 
jcallahan@39
 | 
   630     end
 | 
| 
jcallahan@39
 | 
   631 
 | 
| 
jcallahan@39
 | 
   632 
 | 
| 
jcallahan@32
 | 
   633     function UpdateFactionData()
 | 
| 
jcallahan@32
 | 
   634         for faction_index = 1, MAX_FACTION_INDEX do
 | 
| 
MMOSimca@581
 | 
   635             local faction_table = _G.C_Reputation.GetFactionDataByIndex(faction_index)
 | 
| 
MMOSimca@581
 | 
   636 
 | 
| 
MMOSimca@581
 | 
   637 			if faction_table then
 | 
| 
MMOSimca@581
 | 
   638 				if faction_table.name then
 | 
| 
MMOSimca@581
 | 
   639 					faction_standings[faction_table.name] = STANDING_NAMES[faction_table.currentStanding]
 | 
| 
MMOSimca@581
 | 
   640 				elseif not faction_table.name then
 | 
| 
MMOSimca@581
 | 
   641 					break
 | 
| 
MMOSimca@581
 | 
   642 				end
 | 
| 
MMOSimca@581
 | 
   643 			end
 | 
| 
jcallahan@20
 | 
   644         end
 | 
| 
jcallahan@20
 | 
   645     end
 | 
| 
jcallahan@32
 | 
   646 end -- do-block
 | 
| 
jcallahan@20
 | 
   647 
 | 
| 
jcallahan@48
 | 
   648 
 | 
| 
MMOSimca@429
 | 
   649 local GenericLootUpdate, LootTable
 | 
| 
jcallahan@75
 | 
   650 do
 | 
| 
MMOSimca@429
 | 
   651     function LootTable(entry, loot_type, top_field)
 | 
| 
jcallahan@75
 | 
   652         if top_field then
 | 
| 
jcallahan@75
 | 
   653             entry[top_field] = entry[top_field] or {}
 | 
| 
jcallahan@75
 | 
   654             entry[top_field][loot_type] = entry[top_field][loot_type] or {}
 | 
| 
jcallahan@75
 | 
   655             return entry[top_field][loot_type]
 | 
| 
jcallahan@75
 | 
   656         end
 | 
| 
jcallahan@48
 | 
   657         entry[loot_type] = entry[loot_type] or {}
 | 
| 
jcallahan@75
 | 
   658         return entry[loot_type]
 | 
| 
jcallahan@48
 | 
   659     end
 | 
| 
jcallahan@48
 | 
   660 
 | 
| 
jcallahan@75
 | 
   661     function GenericLootUpdate(data_type, top_field)
 | 
| 
jcallahan@132
 | 
   662         local loot_type = current_loot.label
 | 
| 
jcallahan@75
 | 
   663         local loot_count = ("%s_count"):format(loot_type)
 | 
| 
jcallahan@77
 | 
   664         local source_list = {}
 | 
| 
jcallahan@75
 | 
   665 
 | 
| 
jcallahan@131
 | 
   666         if current_loot.sources then
 | 
| 
jcallahan@131
 | 
   667             for source_guid, loot_data in pairs(current_loot.sources) do
 | 
| 
jcallahan@304
 | 
   668                 local source_id
 | 
| 
jcallahan@78
 | 
   669 
 | 
| 
jcallahan@131
 | 
   670                 if current_loot.target_type == AF.ITEM then
 | 
| 
jcallahan@119
 | 
   671                     -- Items return the player as the source, so we need to use the item's ID (disenchant, milling, etc)
 | 
| 
jcallahan@131
 | 
   672                     source_id = current_loot.identifier
 | 
| 
jcallahan@119
 | 
   673                 else
 | 
| 
jcallahan@331
 | 
   674                     local _, unit_ID = ParseGUID(source_guid)
 | 
| 
MMOSimca@328
 | 
   675                     if unit_ID then
 | 
| 
MMOSimca@328
 | 
   676                         if current_loot.target_type == AF.OBJECT then
 | 
| 
MMOSimca@328
 | 
   677                             source_id = ("%s:%s"):format(current_loot.spell_label, unit_ID)
 | 
| 
MMOSimca@328
 | 
   678                         else
 | 
| 
MMOSimca@328
 | 
   679                             source_id = unit_ID
 | 
| 
MMOSimca@328
 | 
   680                         end
 | 
| 
MMOSimca@328
 | 
   681                     end
 | 
| 
jcallahan@119
 | 
   682                 end
 | 
| 
jcallahan@304
 | 
   683                 local entry = DBEntry(data_type, source_id)
 | 
| 
jcallahan@75
 | 
   684 
 | 
| 
jcallahan@119
 | 
   685                 if entry then
 | 
| 
jcallahan@119
 | 
   686                     local loot_table = LootTable(entry, loot_type, top_field)
 | 
| 
jcallahan@77
 | 
   687 
 | 
| 
jcallahan@304
 | 
   688                     if not source_list[source_id] then
 | 
| 
jcallahan@119
 | 
   689                         if top_field then
 | 
| 
jcallahan@119
 | 
   690                             entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1
 | 
| 
MMOSimca@387
 | 
   691                         elseif not container_loot_toasting then
 | 
| 
jcallahan@119
 | 
   692                             entry[loot_count] = (entry[loot_count] or 0) + 1
 | 
| 
jcallahan@119
 | 
   693                         end
 | 
| 
jcallahan@304
 | 
   694                         source_list[source_id] = true
 | 
| 
jcallahan@77
 | 
   695                     end
 | 
| 
jcallahan@119
 | 
   696                     UpdateDBEntryLocation(data_type, source_id)
 | 
| 
jcallahan@75
 | 
   697 
 | 
| 
jcallahan@309
 | 
   698                     if current_loot.target_type == AF.ZONE then
 | 
| 
jcallahan@309
 | 
   699                         for item_id, quantity in pairs(loot_data) do
 | 
| 
jcallahan@309
 | 
   700                             table.insert(loot_table, ("%d:%d"):format(item_id, quantity))
 | 
| 
jcallahan@309
 | 
   701                         end
 | 
| 
jcallahan@309
 | 
   702                     else
 | 
| 
jcallahan@308
 | 
   703                         for loot_token, quantity in pairs(loot_data) do
 | 
| 
mmosimca@496
 | 
   704                             local label, currency_id = (":"):split(loot_token)
 | 
| 
mmosimca@496
 | 
   705 
 | 
| 
mmosimca@496
 | 
   706                             if label == "currency" and currency_id then
 | 
| 
mmosimca@496
 | 
   707                                 -- Convert currency_id back into number from string
 | 
| 
mmosimca@496
 | 
   708                                 currency_id = tonumber(currency_id) or 0
 | 
| 
mmosimca@496
 | 
   709                                 if currency_id ~= 0 then
 | 
| 
mmosimca@496
 | 
   710                                     table.insert(loot_table, ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
mmosimca@496
 | 
   711                                 end
 | 
| 
jcallahan@308
 | 
   712                             elseif loot_token == "money" then
 | 
| 
jcallahan@308
 | 
   713                                 table.insert(loot_table, ("money:%d"):format(quantity))
 | 
| 
jcallahan@308
 | 
   714                             else
 | 
| 
jcallahan@308
 | 
   715                                 table.insert(loot_table, ("%d:%d"):format(loot_token, quantity))
 | 
| 
jcallahan@308
 | 
   716                             end
 | 
| 
jcallahan@308
 | 
   717                         end
 | 
| 
jcallahan@119
 | 
   718                     end
 | 
| 
jcallahan@75
 | 
   719                 end
 | 
| 
jcallahan@75
 | 
   720             end
 | 
| 
jcallahan@75
 | 
   721         end
 | 
| 
jcallahan@121
 | 
   722 
 | 
| 
jcallahan@121
 | 
   723         -- This is used for Gas Extractions.
 | 
| 
jcallahan@131
 | 
   724         if #current_loot.list <= 0 then
 | 
| 
jcallahan@78
 | 
   725             return
 | 
| 
jcallahan@78
 | 
   726         end
 | 
| 
jcallahan@82
 | 
   727         local entry
 | 
| 
jcallahan@82
 | 
   728 
 | 
| 
jcallahan@82
 | 
   729         -- At this point we only have a name if it's an object.
 | 
| 
MMOSimca@388
 | 
   730         -- (As of 5.x, the above statement is almost never true, but there are a few cases, like gas extractions.)
 | 
| 
jcallahan@131
 | 
   731         if current_loot.target_type == AF.OBJECT then
 | 
| 
jcallahan@131
 | 
   732             entry = DBEntry(data_type, ("%s:%s"):format(current_loot.spell_label, current_loot.object_name))
 | 
| 
jcallahan@82
 | 
   733         else
 | 
| 
jcallahan@131
 | 
   734             entry = DBEntry(data_type, current_loot.identifier)
 | 
| 
jcallahan@82
 | 
   735         end
 | 
| 
jcallahan@75
 | 
   736 
 | 
| 
jcallahan@75
 | 
   737         if not entry then
 | 
| 
jcallahan@75
 | 
   738             return
 | 
| 
jcallahan@75
 | 
   739         end
 | 
| 
jcallahan@77
 | 
   740         local loot_table = LootTable(entry, loot_type, top_field)
 | 
| 
jcallahan@77
 | 
   741 
 | 
| 
jcallahan@307
 | 
   742         if current_loot.identifier then
 | 
| 
jcallahan@307
 | 
   743             if not source_list[current_loot.identifier] then
 | 
| 
jcallahan@307
 | 
   744                 if top_field then
 | 
| 
jcallahan@307
 | 
   745                     entry[top_field][loot_count] = (entry[top_field][loot_count] or 0) + 1
 | 
| 
jcallahan@307
 | 
   746                 else
 | 
| 
jcallahan@307
 | 
   747                     entry[loot_count] = (entry[loot_count] or 0) + 1
 | 
| 
jcallahan@307
 | 
   748                 end
 | 
| 
jcallahan@307
 | 
   749                 source_list[current_loot.identifier] = true
 | 
| 
jcallahan@77
 | 
   750             end
 | 
| 
jcallahan@77
 | 
   751         end
 | 
| 
jcallahan@75
 | 
   752 
 | 
| 
jcallahan@131
 | 
   753         for index = 1, #current_loot.list do
 | 
| 
jcallahan@131
 | 
   754             table.insert(loot_table, current_loot.list[index])
 | 
| 
jcallahan@75
 | 
   755         end
 | 
| 
jcallahan@48
 | 
   756     end
 | 
| 
jcallahan@75
 | 
   757 end -- do-block
 | 
| 
jcallahan@48
 | 
   758 
 | 
| 
jcallahan@97
 | 
   759 
 | 
| 
jcallahan@97
 | 
   760 local ReplaceKeywords
 | 
| 
jcallahan@97
 | 
   761 do
 | 
| 
jcallahan@97
 | 
   762     local KEYWORD_SUBSTITUTIONS = {
 | 
| 
jcallahan@97
 | 
   763         class = PLAYER_CLASS,
 | 
| 
jcallahan@97
 | 
   764         name = PLAYER_NAME,
 | 
| 
jcallahan@97
 | 
   765         race = PLAYER_RACE,
 | 
| 
jcallahan@97
 | 
   766     }
 | 
| 
jcallahan@97
 | 
   767 
 | 
| 
jcallahan@97
 | 
   768 
 | 
| 
jcallahan@97
 | 
   769     function ReplaceKeywords(text)
 | 
| 
jcallahan@97
 | 
   770         if not text or text == "" then
 | 
| 
jcallahan@97
 | 
   771             return ""
 | 
| 
jcallahan@97
 | 
   772         end
 | 
| 
jcallahan@97
 | 
   773 
 | 
| 
jcallahan@97
 | 
   774         for category, lookup in pairs(KEYWORD_SUBSTITUTIONS) do
 | 
| 
jcallahan@97
 | 
   775             local category_format = ("<%s>"):format(category)
 | 
| 
jcallahan@97
 | 
   776             text = text:gsub(lookup, category_format):gsub(lookup:lower(), category_format)
 | 
| 
jcallahan@97
 | 
   777         end
 | 
| 
jcallahan@97
 | 
   778         return text
 | 
| 
jcallahan@97
 | 
   779     end
 | 
| 
jcallahan@97
 | 
   780 end -- do-block
 | 
| 
jcallahan@97
 | 
   781 
 | 
| 
jcallahan@97
 | 
   782 
 | 
| 
MMOSimca@347
 | 
   783 -- TIMERS -------------------------------------------------------------
 | 
| 
MMOSimca@347
 | 
   784 
 | 
| 
MMOSimca@393
 | 
   785 function ClearKilledNPC()
 | 
| 
MMOSimca@347
 | 
   786     killed_npc_id = nil
 | 
| 
MMOSimca@347
 | 
   787 end
 | 
| 
MMOSimca@347
 | 
   788 
 | 
| 
MMOSimca@347
 | 
   789 
 | 
| 
MMOSimca@393
 | 
   790 function ClearKilledBossID()
 | 
| 
MMOSimca@347
 | 
   791     if killed_boss_id_timer_handle then
 | 
| 
MMOSimca@383
 | 
   792         killed_boss_id_timer_handle:Cancel()
 | 
| 
MMOSimca@347
 | 
   793         killed_boss_id_timer_handle = nil
 | 
| 
MMOSimca@347
 | 
   794     end
 | 
| 
MMOSimca@347
 | 
   795 
 | 
| 
MMOSimca@347
 | 
   796     table.wipe(boss_loot_toasting)
 | 
| 
MMOSimca@387
 | 
   797     raid_boss_id = nil
 | 
| 
MMOSimca@347
 | 
   798 end
 | 
| 
MMOSimca@347
 | 
   799 
 | 
| 
MMOSimca@347
 | 
   800 
 | 
| 
MMOSimca@393
 | 
   801 function ClearLootToastContainerID()
 | 
| 
MMOSimca@347
 | 
   802     if loot_toast_container_timer_handle then
 | 
| 
MMOSimca@383
 | 
   803         loot_toast_container_timer_handle:Cancel()
 | 
| 
MMOSimca@347
 | 
   804         loot_toast_container_timer_handle = nil
 | 
| 
MMOSimca@347
 | 
   805     end
 | 
| 
MMOSimca@347
 | 
   806 
 | 
| 
MMOSimca@387
 | 
   807     container_loot_toasting = false
 | 
| 
MMOSimca@387
 | 
   808     loot_toast_container_id = nil
 | 
| 
MMOSimca@347
 | 
   809 end
 | 
| 
MMOSimca@347
 | 
   810 
 | 
| 
MMOSimca@347
 | 
   811 
 | 
| 
MMOSimca@393
 | 
   812 function ClearLootToastData()
 | 
| 
MMOSimca@347
 | 
   813     if loot_toast_data_timer_handle then
 | 
| 
MMOSimca@383
 | 
   814         loot_toast_data_timer_handle:Cancel()
 | 
| 
MMOSimca@347
 | 
   815         loot_toast_data_timer_handle = nil
 | 
| 
MMOSimca@347
 | 
   816     end
 | 
| 
MMOSimca@347
 | 
   817 
 | 
| 
MMOSimca@347
 | 
   818     if loot_toast_data then
 | 
| 
MMOSimca@347
 | 
   819         table.wipe(loot_toast_data)
 | 
| 
MMOSimca@347
 | 
   820     end
 | 
| 
MMOSimca@347
 | 
   821 end
 | 
| 
MMOSimca@347
 | 
   822 
 | 
| 
MMOSimca@347
 | 
   823 
 | 
| 
MMOSimca@393
 | 
   824 function ClearChatLootData()
 | 
| 
MMOSimca@398
 | 
   825     if not chat_loot_timer_handle then
 | 
| 
MMOSimca@435
 | 
   826         table.wipe(chat_loot_data)
 | 
| 
MMOSimca@398
 | 
   827         return
 | 
| 
MMOSimca@398
 | 
   828     end
 | 
| 
MMOSimca@398
 | 
   829     Debug("ClearChatLootData: Ending chat-based loot timer.")
 | 
| 
MMOSimca@398
 | 
   830     chat_loot_timer_handle:Cancel()
 | 
| 
MMOSimca@398
 | 
   831     chat_loot_timer_handle = nil
 | 
| 
atcaleb@573
 | 
   832     
 | 
| 
atcaleb@573
 | 
   833     -- Slimmed down (and more importantly, separate) versions of GenericLootUpdate, specifically for chat_loot_data
 | 
| 
atcaleb@573
 | 
   834     -- First version is for special item containers that 'push' loot without using a loot window
 | 
| 
atcaleb@573
 | 
   835     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
 | 
| 
MMOSimca@414
 | 
   836         local entry = DBEntry("items", chat_loot_data.identifier)
 | 
| 
MMOSimca@414
 | 
   837 
 | 
| 
MMOSimca@414
 | 
   838         if entry then
 | 
| 
MMOSimca@414
 | 
   839             local loot_table = LootTable(entry, "contains")
 | 
| 
MMOSimca@414
 | 
   840             entry["contains_count"] = (entry["contains_count"] or 0) + 1
 | 
| 
MMOSimca@414
 | 
   841 
 | 
| 
MMOSimca@435
 | 
   842             for loot_token, quantity in pairs(chat_loot_data.loot) do
 | 
| 
mmosimca@496
 | 
   843                 local label, currency_id = (":"):split(loot_token)
 | 
| 
mmosimca@496
 | 
   844 
 | 
| 
mmosimca@496
 | 
   845                 if label == "currency" and currency_id then
 | 
| 
mmosimca@496
 | 
   846                     -- Convert currency_id back into number from string
 | 
| 
mmosimca@496
 | 
   847                     currency_id = tonumber(currency_id) or 0
 | 
| 
mmosimca@496
 | 
   848                     if currency_id ~= 0 then
 | 
| 
mmosimca@496
 | 
   849                         table.insert(loot_table, ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
mmosimca@496
 | 
   850                     end
 | 
| 
MMOSimca@414
 | 
   851                 elseif loot_token == "money" then
 | 
| 
MMOSimca@414
 | 
   852                     table.insert(loot_table, ("money:%d"):format(quantity))
 | 
| 
MMOSimca@414
 | 
   853                 else
 | 
| 
MMOSimca@414
 | 
   854                     table.insert(loot_table, ("%d:%d"):format(loot_token, quantity))
 | 
| 
MMOSimca@414
 | 
   855                 end
 | 
| 
MMOSimca@414
 | 
   856             end
 | 
| 
MMOSimca@414
 | 
   857         end
 | 
| 
atcaleb@573
 | 
   858     -- Second version is for Island Expeditions. This code is flawed (by design).
 | 
| 
atcaleb@573
 | 
   859     elseif chat_loot_data.loot and chat_loot_data.category == AF.NPC then
 | 
| 
atcaleb@573
 | 
   860         -- Iterate over all NPCs killed in an island expedition (at least by your team)
 | 
| 
atcaleb@573
 | 
   861         for island_npc_id, kill_count in pairs(killed_npcs_in_island) do
 | 
| 
atcaleb@573
 | 
   862             local npc = NPCEntry(island_npc_id)
 | 
| 
atcaleb@573
 | 
   863             if npc then
 | 
| 
atcaleb@573
 | 
   864                 -- Create needed npc fields if required
 | 
| 
atcaleb@573
 | 
   865                 local loot_label = "drops"
 | 
| 
atcaleb@573
 | 
   866                 local encounter_data = npc:EncounterData(InstanceDifficultyToken())
 | 
| 
atcaleb@573
 | 
   867                 encounter_data[loot_label] = encounter_data[loot_label] or {}
 | 
| 
atcaleb@573
 | 
   868                 encounter_data.loot_counts = encounter_data.loot_counts or {}
 | 
| 
atcaleb@573
 | 
   869                 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + kill_count
 | 
| 
atcaleb@573
 | 
   870 
 | 
| 
atcaleb@573
 | 
   871                 for loot_token, quantity in pairs(chat_loot_data.loot) do
 | 
| 
atcaleb@573
 | 
   872                     local label, currency_id = (":"):split(loot_token)
 | 
| 
atcaleb@573
 | 
   873 
 | 
| 
atcaleb@573
 | 
   874                     -- Only support items
 | 
| 
atcaleb@573
 | 
   875                     if (label ~= "currency" or not currency_id) and (loot_token ~= "money") then
 | 
| 
atcaleb@573
 | 
   876                         -- Ignore certain items (dubloon bags)
 | 
| 
atcaleb@573
 | 
   877                         if not private.IGNORED_ISLAND_REWARDS[tonumber(loot_token)] then
 | 
| 
atcaleb@573
 | 
   878                             table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
 | 
| 
atcaleb@573
 | 
   879                         end
 | 
| 
atcaleb@573
 | 
   880                     end
 | 
| 
atcaleb@573
 | 
   881                 end
 | 
| 
atcaleb@573
 | 
   882             end
 | 
| 
atcaleb@573
 | 
   883         end
 | 
| 
MMOSimca@347
 | 
   884     end
 | 
| 
atcaleb@573
 | 
   885     table.wipe(killed_npcs_in_island)
 | 
| 
MMOSimca@435
 | 
   886     table.wipe(chat_loot_data)
 | 
| 
MMOSimca@347
 | 
   887 end
 | 
| 
MMOSimca@347
 | 
   888 
 | 
| 
MMOSimca@347
 | 
   889 
 | 
| 
jcallahan@246
 | 
   890 -- METHODS ------------------------------------------------------------
 | 
| 
jcallahan@246
 | 
   891 
 | 
| 
jcallahan@0
 | 
   892 function WDP:OnInitialize()
 | 
| 
jcallahan@128
 | 
   893     local db = LibStub("AceDB-3.0"):New("WoWDBProfilerData", DATABASE_DEFAULTS, "Default")
 | 
| 
jcallahan@270
 | 
   894     private.db = db
 | 
| 
jcallahan@128
 | 
   895     global_db = db.global
 | 
| 
jcallahan@128
 | 
   896     char_db = db.char
 | 
| 
jcallahan@14
 | 
   897 
 | 
| 
jcallahan@270
 | 
   898     local raw_db = _G.WoWDBProfilerData
 | 
| 
jcallahan@18
 | 
   899     local build_num = tonumber(private.build_num)
 | 
| 
mmosimca@485
 | 
   900 
 | 
| 
MMOSimca@533
 | 
   901     -- Get current region from API (flawed)
 | 
| 
MMOSimca@533
 | 
   902     local current_region = _G.GetCurrentRegionName() or "XX"
 | 
| 
mmosimca@484
 | 
   903 
 | 
| 
mmosimca@484
 | 
   904     -- Wipe all data if DB version or build number changed
 | 
| 
jcallahan@136
 | 
   905     if (raw_db.version and raw_db.version < DB_VERSION) or (raw_db.build_num and raw_db.build_num < build_num) then
 | 
| 
jcallahan@74
 | 
   906         for entry in pairs(DATABASE_DEFAULTS.global) do
 | 
| 
jcallahan@128
 | 
   907             global_db[entry] = {}
 | 
| 
jcallahan@74
 | 
   908         end
 | 
| 
jcallahan@74
 | 
   909     end
 | 
| 
mmosimca@485
 | 
   910     -- Wipe World Quest data if region changed
 | 
| 
mmosimca@485
 | 
   911     if raw_db.region and raw_db.region ~= current_region and global_db["world_quests"] then
 | 
| 
mmosimca@485
 | 
   912         global_db["world_quests"] = {}
 | 
| 
mmosimca@485
 | 
   913     end
 | 
| 
mmosimca@485
 | 
   914 
 | 
| 
jcallahan@35
 | 
   915     raw_db.build_num = build_num
 | 
| 
mmosimca@484
 | 
   916     raw_db.region = current_region
 | 
| 
jcallahan@63
 | 
   917     raw_db.version = DB_VERSION
 | 
| 
jcallahan@249
 | 
   918 
 | 
| 
jcallahan@312
 | 
   919     private.InitializeCommentSystem()
 | 
| 
jcallahan@312
 | 
   920     self:RegisterChatCommand("comment", private.ProcessCommentCommand)
 | 
| 
jcallahan@0
 | 
   921 end
 | 
| 
jcallahan@0
 | 
   922 
 | 
| 
jcallahan@0
 | 
   923 
 | 
| 
jcallahan@153
 | 
   924 function WDP:EventDispatcher(...)
 | 
| 
jcallahan@153
 | 
   925     local event_name = ...
 | 
| 
jcallahan@153
 | 
   926 
 | 
| 
MMOSimca@346
 | 
   927     if DEBUGGING then
 | 
| 
jcallahan@154
 | 
   928         if event_name == "COMBAT_LOG_EVENT_UNFILTERED" then
 | 
| 
jcallahan@154
 | 
   929             Debug(event_name)
 | 
| 
jcallahan@154
 | 
   930         else
 | 
| 
jcallahan@154
 | 
   931             Debug(...)
 | 
| 
jcallahan@153
 | 
   932         end
 | 
| 
jcallahan@153
 | 
   933     end
 | 
| 
jcallahan@153
 | 
   934     local func = EVENT_MAPPING[event_name]
 | 
| 
jcallahan@153
 | 
   935 
 | 
| 
mmosimca@522
 | 
   936     if type(func) == "boolean" then
 | 
| 
jcallahan@153
 | 
   937         self[event_name](self, ...)
 | 
| 
mmosimca@522
 | 
   938     elseif type(func) == "function" then
 | 
| 
jcallahan@159
 | 
   939         self[func](self, ...)
 | 
| 
jcallahan@153
 | 
   940     end
 | 
| 
jcallahan@153
 | 
   941 end
 | 
| 
jcallahan@153
 | 
   942 
 | 
| 
jcallahan@153
 | 
   943 
 | 
| 
jcallahan@0
 | 
   944 function WDP:OnEnable()
 | 
| 
jcallahan@300
 | 
   945     PLAYER_GUID = _G.UnitGUID("player")
 | 
| 
jcallahan@300
 | 
   946 
 | 
| 
jcallahan@0
 | 
   947     for event_name, mapping in pairs(EVENT_MAPPING) do
 | 
| 
jcallahan@156
 | 
   948         if EVENT_DEBUG then
 | 
| 
jcallahan@153
 | 
   949             self:RegisterEvent(event_name, "EventDispatcher")
 | 
| 
jcallahan@153
 | 
   950         else
 | 
| 
mmosimca@522
 | 
   951             self:RegisterEvent(event_name, (type(mapping) ~= "boolean") and mapping or nil)
 | 
| 
jcallahan@153
 | 
   952         end
 | 
| 
jcallahan@0
 | 
   953     end
 | 
| 
jcallahan@95
 | 
   954 
 | 
| 
mmosimca@496
 | 
   955     -- Gather known languages
 | 
| 
jcallahan@95
 | 
   956     for index = 1, _G.GetNumLanguages() do
 | 
| 
jcallahan@95
 | 
   957         languages_known[_G.GetLanguageByIndex(index)] = true
 | 
| 
jcallahan@95
 | 
   958     end
 | 
| 
mmosimca@518
 | 
   959 
 | 
| 
mmosimca@485
 | 
   960     -- These timers loop indefinitely using Lua's infinity constant
 | 
| 
atcaleb@562
 | 
   961     item_process_timer_handle = C_Timer.NewTicker(DELAY_PROCESS_ITEMS, WDP.ProcessItems, nil)
 | 
| 
atcaleb@562
 | 
   962     target_location_timer_handle = C_Timer.NewTicker(DELAY_UPDATE_TARGET_LOCATION, WDP.UpdateTargetLocation, nil)
 | 
| 
atcaleb@562
 | 
   963     world_quest_timer_handle = C_Timer.NewTicker(DELAY_PROCESS_WORLD_QUESTS, WDP.ProcessWorldQuests, nil)
 | 
| 
jcallahan@19
 | 
   964 
 | 
| 
MMOSimca@581
 | 
   965     _G.hooksecurefunc(C_Container, "UseContainerItem", function(bag_index, slot_index, target_unit)
 | 
| 
jcallahan@19
 | 
   966         if target_unit then
 | 
| 
jcallahan@19
 | 
   967             return
 | 
| 
jcallahan@19
 | 
   968         end
 | 
| 
MMOSimca@581
 | 
   969         HandleItemUse(_G.C_Container.GetContainerItemLink(bag_index, slot_index), bag_index, slot_index)
 | 
| 
jcallahan@19
 | 
   970     end)
 | 
| 
jcallahan@19
 | 
   971 
 | 
| 
MMOSimca@584
 | 
   972     _G.hooksecurefunc(C_Item, "UseItemByName", function(identifier, target_unit)
 | 
| 
jcallahan@19
 | 
   973         if target_unit then
 | 
| 
jcallahan@19
 | 
   974             return
 | 
| 
jcallahan@19
 | 
   975         end
 | 
| 
jcallahan@19
 | 
   976         local _, item_link = _G.GetItemInfo(identifier)
 | 
| 
jcallahan@19
 | 
   977         HandleItemUse(item_link)
 | 
| 
jcallahan@19
 | 
   978     end)
 | 
| 
jcallahan@263
 | 
   979 
 | 
| 
jcallahan@290
 | 
   980     self:GROUP_ROSTER_UPDATE()
 | 
| 
jcallahan@0
 | 
   981 end
 | 
| 
jcallahan@0
 | 
   982 
 | 
| 
jcallahan@0
 | 
   983 
 | 
| 
mmosimca@485
 | 
   984 -- Record data for a specific quest ID; reward data must be available or nothing will be recorded
 | 
| 
mmosimca@485
 | 
   985 -- When we reach this point, we've already checked for a valid mapID, questID, quest data, and worldQuestType
 | 
| 
atcaleb@562
 | 
   986 local function RecordWorldQuestData(quest_id, api_data_table)
 | 
| 
atcaleb@575
 | 
   987     local xp, _ = _G.GetQuestLogRewardXP(quest_id)
 | 
| 
atcaleb@575
 | 
   988 
 | 
| 
mmosimca@485
 | 
   989     -- Ensure we have location data and rewards (barely readable so putting it on multiple lines)
 | 
| 
mmosimca@487
 | 
   990     -- (Honor is built in to the quest; it is not a sign rewards have been loaded)
 | 
| 
atcaleb@562
 | 
   991     if not api_data_table or not api_data_table.x or not api_data_table.y or not api_data_table.mapID or not
 | 
| 
atcaleb@575
 | 
   992       (xp > 0 or _G.GetNumQuestLogRewardCurrencies(quest_id) > 0
 | 
| 
atcaleb@562
 | 
   993       or _G.GetNumQuestLogRewards(quest_id) > 0 or _G.GetQuestLogRewardMoney(quest_id) > 0) then
 | 
| 
atcaleb@562
 | 
   994     --or _G.GetQuestLogRewardArtifactXP(quest_id) > 0)
 | 
| 
mmosimca@485
 | 
   995         return
 | 
| 
mmosimca@485
 | 
   996     end
 | 
| 
mmosimca@485
 | 
   997 
 | 
| 
mmosimca@485
 | 
   998     local entry = DBEntry("world_quests", quest_id)
 | 
| 
mmosimca@485
 | 
   999     if entry then
 | 
| 
mmosimca@485
 | 
  1000 
 | 
| 
mmosimca@485
 | 
  1001         -- Record location
 | 
| 
mmosimca@485
 | 
  1002         entry["location"] = {}
 | 
| 
atcaleb@562
 | 
  1003         entry["location"]["world_map_id"] = api_data_table.mapID
 | 
| 
atcaleb@562
 | 
  1004         entry["location"]["x"] = api_data_table.x * 100
 | 
| 
atcaleb@562
 | 
  1005         entry["location"]["y"] = api_data_table.y * 100
 | 
| 
mmosimca@485
 | 
  1006 
 | 
| 
mmosimca@485
 | 
  1007         -- Record simple rewards (XP, money, artifact XP, honor)
 | 
| 
mmosimca@485
 | 
  1008         entry["rewards"] = {}
 | 
| 
atcaleb@575
 | 
  1009         entry["rewards"]["xp"] = tonumber(xp) or 0
 | 
| 
mmosimca@485
 | 
  1010         entry["rewards"]["money"] = tonumber(_G.GetQuestLogRewardMoney(quest_id)) or 0
 | 
| 
atcaleb@562
 | 
  1011         --local actualXP, scaling = _G.GetQuestLogRewardArtifactXP(quest_id)
 | 
| 
atcaleb@562
 | 
  1012         --entry["rewards"]["artifact_xp"] = ("%d:%d"):format(tonumber(actualXP) or 0, tonumber(scaling) or 0)
 | 
| 
mmosimca@485
 | 
  1013         entry["rewards"]["honor"] = tonumber(_G.GetQuestLogRewardHonor(quest_id)) or 0
 | 
| 
mmosimca@485
 | 
  1014 
 | 
| 
mmosimca@485
 | 
  1015         -- Record currencies
 | 
| 
mmosimca@485
 | 
  1016         entry["rewards"]["currency_count"] = tonumber(_G.GetNumQuestLogRewardCurrencies(quest_id)) or 0
 | 
| 
mmosimca@485
 | 
  1017 
 | 
| 
mmosimca@496
 | 
  1018         -- Create currency rewards sub-table and fill
 | 
| 
mmosimca@485
 | 
  1019         if entry["rewards"]["currency_count"] > 0 then
 | 
| 
mmosimca@485
 | 
  1020             entry["rewards"]["currencies"] = {}
 | 
| 
mmosimca@485
 | 
  1021             for i = 1, entry["rewards"]["currency_count"] do
 | 
| 
mmosimca@503
 | 
  1022                 local name, texture_path, quantity, currency_id = _G.GetQuestLogRewardCurrencyInfo(i, quest_id)
 | 
| 
mmosimca@503
 | 
  1023                 table.insert(entry["rewards"]["currencies"], ("%d:%d"):format(quantity, currency_id))
 | 
| 
mmosimca@485
 | 
  1024             end
 | 
| 
mmosimca@485
 | 
  1025         end
 | 
| 
mmosimca@485
 | 
  1026 
 | 
| 
mmosimca@485
 | 
  1027         -- Record items
 | 
| 
mmosimca@485
 | 
  1028         entry["rewards"]["item_count"] = tonumber(_G.GetNumQuestLogRewards(quest_id)) or 0
 | 
| 
mmosimca@485
 | 
  1029 
 | 
| 
mmosimca@496
 | 
  1030         -- Create item rewards sub-table and fill
 | 
| 
mmosimca@485
 | 
  1031         if entry["rewards"]["item_count"] > 0 then
 | 
| 
mmosimca@485
 | 
  1032             entry["rewards"]["items"] = {}
 | 
| 
mmosimca@485
 | 
  1033             for i = 1, entry["rewards"]["item_count"] do
 | 
| 
mmosimca@485
 | 
  1034                 local item_name, item_texture, quantity, quality, is_usable, item_id = _G.GetQuestLogRewardInfo(i, quest_id)
 | 
| 
mmosimca@485
 | 
  1035                 table.insert(entry["rewards"]["items"], ("%d:%d"):format(item_id, quantity))
 | 
| 
mmosimca@485
 | 
  1036             end
 | 
| 
mmosimca@485
 | 
  1037         end
 | 
| 
mmosimca@485
 | 
  1038 
 | 
| 
mmosimca@485
 | 
  1039         -- Record time remaining
 | 
| 
mmosimca@485
 | 
  1040         entry["estimated_end_time"] = _G.GetServerTime() + ((_G.C_TaskQuest.GetQuestTimeLeftMinutes(quest_id) or 0) * 60)
 | 
| 
mmosimca@485
 | 
  1041     end
 | 
| 
mmosimca@485
 | 
  1042 end
 | 
| 
mmosimca@485
 | 
  1043 
 | 
| 
mmosimca@485
 | 
  1044 
 | 
| 
mmosimca@485
 | 
  1045 function WDP:ProcessWorldQuests()
 | 
| 
MMOSimca@532
 | 
  1046     -- Ignore if player is low level (there are some world quests before max level now, but we can collect enough data from 110s alone still)
 | 
| 
atcaleb@562
 | 
  1047     if _G.UnitLevel("player") < 110 then return end
 | 
| 
atcaleb@559
 | 
  1048 
 | 
| 
atcaleb@566
 | 
  1049     -- Check all first-order continents
 | 
| 
atcaleb@566
 | 
  1050     local continents = C_Map.GetMapChildrenInfo(UI_MAP_COSMIC, Enum.UIMapType.Continent, true);
 | 
| 
atcaleb@566
 | 
  1051     for i, continentInfo in ipairs(continents) do
 | 
| 
atcaleb@566
 | 
  1052         
 | 
| 
atcaleb@566
 | 
  1053         -- Get continent data for World Quests
 | 
| 
atcaleb@566
 | 
  1054         local continent_api_data = C_TaskQuest.GetQuestsForPlayerByMapID(continentInfo.mapID)
 | 
| 
atcaleb@566
 | 
  1055 
 | 
| 
atcaleb@566
 | 
  1056         -- If the continent has WQ data, continue
 | 
| 
atcaleb@566
 | 
  1057         if continent_api_data and type(continent_api_data) == "table" and #continent_api_data > 0 then
 | 
| 
atcaleb@566
 | 
  1058             -- Iterate over zones on continents
 | 
| 
atcaleb@566
 | 
  1059             local zones = C_Map.GetMapChildrenInfo(continentInfo.mapID, Enum.UIMapType.Zone)
 | 
| 
atcaleb@566
 | 
  1060             for j, zoneInfo in ipairs(zones) do
 | 
| 
atcaleb@566
 | 
  1061 
 | 
| 
atcaleb@566
 | 
  1062                 -- Get zone data for World Quests
 | 
| 
atcaleb@566
 | 
  1063                 local zone_api_data = C_TaskQuest.GetQuestsForPlayerByMapID(zoneInfo.mapID);
 | 
| 
atcaleb@566
 | 
  1064 
 | 
| 
atcaleb@566
 | 
  1065                 -- Iterate over the questIDs for each zone, doing preload reward requests and creating SavedVariables entries
 | 
| 
atcaleb@566
 | 
  1066                 if zone_api_data and type(zone_api_data) == "table" and #zone_api_data > 0 then
 | 
| 
atcaleb@566
 | 
  1067                     for k = 1, #zone_api_data do
 | 
| 
atcaleb@566
 | 
  1068 
 | 
| 
atcaleb@566
 | 
  1069                         -- Check if we had a valid API table returned to us
 | 
| 
atcaleb@566
 | 
  1070                         if zone_api_data[k] and type(zone_api_data[k]) == "table" and zone_api_data[k].questId then
 | 
| 
atcaleb@566
 | 
  1071                             local quest_id = tonumber(zone_api_data[k].questId) or 0
 | 
| 
atcaleb@566
 | 
  1072 
 | 
| 
atcaleb@566
 | 
  1073                             -- Check if we have quest data and the quest is within this zone directly
 | 
| 
atcaleb@566
 | 
  1074                             if quest_id > 0 and _G.HaveQuestData(quest_id) and QuestUtils_IsQuestWorldQuest(quest_id) and zone_api_data[k].mapID == zoneInfo.mapID then
 | 
| 
atcaleb@566
 | 
  1075                                 _G.C_TaskQuest.RequestPreloadRewardData(quest_id)
 | 
| 
atcaleb@566
 | 
  1076                                 RecordWorldQuestData(quest_id, zone_api_data[k])
 | 
| 
atcaleb@566
 | 
  1077                             end
 | 
| 
atcaleb@566
 | 
  1078                         end
 | 
| 
mmosimca@485
 | 
  1079                     end
 | 
| 
mmosimca@485
 | 
  1080                 end
 | 
| 
mmosimca@485
 | 
  1081             end
 | 
| 
mmosimca@485
 | 
  1082         end
 | 
| 
mmosimca@485
 | 
  1083     end
 | 
| 
mmosimca@485
 | 
  1084 end
 | 
| 
mmosimca@485
 | 
  1085 
 | 
| 
mmosimca@485
 | 
  1086 
 | 
| 
MMOSimca@340
 | 
  1087 local function RecordItemData(item_id, item_link, process_bonus_ids, durability)
 | 
| 
jcallahan@331
 | 
  1088     local _, _, item_string = item_link:find("^|%x+|H(.+)|h%[.+%]")
 | 
| 
jcallahan@219
 | 
  1089     local item
 | 
| 
jcallahan@0
 | 
  1090 
 | 
| 
jcallahan@191
 | 
  1091     if item_string then
 | 
| 
MMOSimca@338
 | 
  1092         local item_results = { (":"):split(item_string) }
 | 
| 
MMOSimca@338
 | 
  1093 
 | 
| 
MMOSimca@460
 | 
  1094         local suffix_id = tonumber(item_results[8]) or 0
 | 
| 
MMOSimca@462
 | 
  1095         local unique_id = tonumber(item_results[9]) or 0
 | 
| 
MMOSimca@447
 | 
  1096         --local level = tonumber(item_results[10])
 | 
| 
MMOSimca@460
 | 
  1097         --local specialization_id = tonumber(item_results[11])
 | 
| 
catherton@469
 | 
  1098         --local upgrade_type_id = tonumber(item_results[12])
 | 
| 
MMOSimca@460
 | 
  1099         local instance_difficulty_id = tonumber(item_results[13]) or 0
 | 
| 
MMOSimca@460
 | 
  1100         local num_bonus_ids = tonumber(item_results[14]) or 0
 | 
| 
catherton@471
 | 
  1101         -- upgrade_value is optional in 6.2! can be detected using upgrade_type_id, but it's just as easy to check like this
 | 
| 
catherton@469
 | 
  1102         local upgrade_value = tonumber(item_results[15 + num_bonus_ids]) or 0
 | 
| 
catherton@465
 | 
  1103 
 | 
| 
mmosimca@484
 | 
  1104         local unk_item_field_1 = tonumber(item_results[16 + num_bonus_ids]) or 0
 | 
| 
mmosimca@484
 | 
  1105         local unk_item_field_2 = tonumber(item_results[17 + num_bonus_ids]) or 0
 | 
| 
mmosimca@484
 | 
  1106         --if unk_item_field_1 > 0 then Debug("unk_item_field_1 for %s is non-zero, specifically %d.", item_link, unk_item_field_1) end
 | 
| 
mmosimca@484
 | 
  1107         --if unk_item_field_2 > 0 then Debug("unk_item_field_2 for %s is non-zero, specifically %d.", item_link, unk_item_field_2) end
 | 
| 
MMOSimca@460
 | 
  1108 
 | 
| 
MMOSimca@460
 | 
  1109         -- If there is anything special (non-zero) for this item then we need to make note of everything
 | 
| 
catherton@471
 | 
  1110         if math.max(suffix_id, instance_difficulty_id, num_bonus_ids, upgrade_value) ~= 0 then
 | 
| 
MMOSimca@460
 | 
  1111             item = DBEntry("items", item_id)
 | 
| 
MMOSimca@460
 | 
  1112             item.suffix_id = suffix_id
 | 
| 
MMOSimca@460
 | 
  1113             item.unique_id = bit.band(unique_id, 0xFFFF)
 | 
| 
MMOSimca@460
 | 
  1114             item.instance_difficulty_id = instance_difficulty_id
 | 
| 
catherton@471
 | 
  1115             item.upgrade_value = upgrade_value
 | 
| 
MMOSimca@460
 | 
  1116 
 | 
| 
MMOSimca@460
 | 
  1117             if process_bonus_ids then
 | 
| 
MMOSimca@460
 | 
  1118 
 | 
| 
MMOSimca@460
 | 
  1119                 -- Get ready for bonus IDs
 | 
| 
MMOSimca@384
 | 
  1120                 if not item.seen_bonuses then
 | 
| 
MMOSimca@384
 | 
  1121                     item.seen_bonuses = {}
 | 
| 
MMOSimca@372
 | 
  1122                 end
 | 
| 
catherton@465
 | 
  1123 
 | 
| 
MMOSimca@460
 | 
  1124                 if num_bonus_ids > 0 then
 | 
| 
MMOSimca@460
 | 
  1125                     -- We want the bonus ID combo output to be in the form ["bonusID1:bonusID2:bonusID3"] = true
 | 
| 
MMOSimca@460
 | 
  1126                     -- And sorted numerically with the smallest bonusID first
 | 
| 
MMOSimca@460
 | 
  1127                     local sorted_bonus_string = ""
 | 
| 
MMOSimca@460
 | 
  1128                     local min_bonus_id_array = {}
 | 
| 
MMOSimca@460
 | 
  1129                     for iterations = 1, num_bonus_ids do
 | 
| 
MMOSimca@460
 | 
  1130                         -- Find minimum of this iteration
 | 
| 
MMOSimca@460
 | 
  1131                         local min_bonus_id = 100000
 | 
| 
MMOSimca@460
 | 
  1132                         for bonus_index = 1, num_bonus_ids do
 | 
| 
MMOSimca@460
 | 
  1133                             local temp_bonus_id = tonumber(item_results[14 + bonus_index])
 | 
| 
MMOSimca@460
 | 
  1134                             if temp_bonus_id and (not min_bonus_id_array[temp_bonus_id]) and (temp_bonus_id < min_bonus_id) then
 | 
| 
MMOSimca@460
 | 
  1135                                 min_bonus_id = temp_bonus_id
 | 
| 
MMOSimca@460
 | 
  1136                             end
 | 
| 
MMOSimca@460
 | 
  1137                         end
 | 
| 
MMOSimca@460
 | 
  1138 
 | 
| 
MMOSimca@460
 | 
  1139                         -- Keep track of already processed IDs
 | 
| 
MMOSimca@460
 | 
  1140                         min_bonus_id_array[min_bonus_id] = true
 | 
| 
MMOSimca@460
 | 
  1141 
 | 
| 
MMOSimca@460
 | 
  1142                         -- Build string
 | 
| 
MMOSimca@460
 | 
  1143                         if iterations == 1 then
 | 
| 
MMOSimca@460
 | 
  1144                             sorted_bonus_string = sorted_bonus_string .. tostring(min_bonus_id)
 | 
| 
MMOSimca@460
 | 
  1145                         else
 | 
| 
MMOSimca@460
 | 
  1146                             sorted_bonus_string = sorted_bonus_string .. ":" .. tostring(min_bonus_id)
 | 
| 
MMOSimca@460
 | 
  1147                         end
 | 
| 
MMOSimca@384
 | 
  1148                     end
 | 
| 
MMOSimca@460
 | 
  1149 
 | 
| 
MMOSimca@460
 | 
  1150                     item.seen_bonuses[sorted_bonus_string] = true
 | 
| 
MMOSimca@460
 | 
  1151                     Debug("RecordItemData: Recorded bonus IDs %s for item %d.", sorted_bonus_string, item_id)
 | 
| 
MMOSimca@384
 | 
  1152                 else
 | 
| 
MMOSimca@460
 | 
  1153                     item.seen_bonuses["0"] = true
 | 
| 
MMOSimca@384
 | 
  1154                 end
 | 
| 
MMOSimca@329
 | 
  1155             end
 | 
| 
jcallahan@191
 | 
  1156         end
 | 
| 
jcallahan@0
 | 
  1157     end
 | 
| 
jcallahan@212
 | 
  1158 
 | 
| 
jcallahan@212
 | 
  1159     if durability and durability > 0 then
 | 
| 
jcallahan@219
 | 
  1160         item = item or DBEntry("items", item_id)
 | 
| 
jcallahan@212
 | 
  1161         item.durability = durability
 | 
| 
jcallahan@212
 | 
  1162     end
 | 
| 
jcallahan@0
 | 
  1163 end
 | 
| 
jcallahan@0
 | 
  1164 
 | 
| 
jcallahan@0
 | 
  1165 
 | 
| 
jcallahan@187
 | 
  1166 function WDP:ProcessItems()
 | 
| 
jcallahan@187
 | 
  1167     for slot_index = _G.INVSLOT_FIRST_EQUIPPED, _G.INVSLOT_LAST_EQUIPPED do
 | 
| 
jcallahan@1
 | 
  1168         local item_id = _G.GetInventoryItemID("player", slot_index)
 | 
| 
jcallahan@0
 | 
  1169 
 | 
| 
jcallahan@0
 | 
  1170         if item_id and item_id > 0 then
 | 
| 
jcallahan@1
 | 
  1171             local _, max_durability = _G.GetInventoryItemDurability(slot_index)
 | 
| 
MMOSimca@340
 | 
  1172             RecordItemData(item_id, _G.GetInventoryItemLink("player", slot_index), false, max_durability)
 | 
| 
jcallahan@0
 | 
  1173         end
 | 
| 
jcallahan@0
 | 
  1174     end
 | 
| 
jcallahan@0
 | 
  1175 
 | 
| 
jcallahan@0
 | 
  1176     for bag_index = 0, _G.NUM_BAG_SLOTS do
 | 
| 
MMOSimca@581
 | 
  1177         for slot_index = 1, _G.C_Container.GetContainerNumSlots(bag_index) do
 | 
| 
MMOSimca@581
 | 
  1178             local item_id = _G.C_Container.GetContainerItemID(bag_index, slot_index)
 | 
| 
jcallahan@0
 | 
  1179 
 | 
| 
jcallahan@0
 | 
  1180             if item_id and item_id > 0 then
 | 
| 
MMOSimca@581
 | 
  1181                 local _, max_durability = _G.C_Container.GetContainerItemDurability(bag_index, slot_index)
 | 
| 
MMOSimca@581
 | 
  1182                 RecordItemData(item_id, _G.C_Container.GetContainerItemLink(bag_index, slot_index), false, max_durability)
 | 
| 
jcallahan@0
 | 
  1183             end
 | 
| 
jcallahan@0
 | 
  1184         end
 | 
| 
jcallahan@0
 | 
  1185     end
 | 
| 
jcallahan@0
 | 
  1186 end
 | 
| 
jcallahan@0
 | 
  1187 
 | 
| 
jcallahan@118
 | 
  1188 
 | 
| 
atcaleb@558
 | 
  1189 local function TargetedNPC()
 | 
| 
atcaleb@558
 | 
  1190     if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or currently_drunk then
 | 
| 
atcaleb@558
 | 
  1191         current_target_id = nil
 | 
| 
atcaleb@558
 | 
  1192         return
 | 
| 
atcaleb@558
 | 
  1193     end
 | 
| 
atcaleb@558
 | 
  1194     local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("target"))
 | 
| 
atcaleb@558
 | 
  1195 
 | 
| 
atcaleb@558
 | 
  1196     if not unit_idnum or not UnitTypeIsNPC(unit_type) then
 | 
| 
atcaleb@558
 | 
  1197         return
 | 
| 
atcaleb@558
 | 
  1198     end
 | 
| 
atcaleb@558
 | 
  1199     current_target_id = unit_idnum
 | 
| 
atcaleb@558
 | 
  1200 
 | 
| 
atcaleb@558
 | 
  1201     local npc = NPCEntry(unit_idnum)
 | 
| 
atcaleb@558
 | 
  1202     local _, class_token = _G.UnitClass("target")
 | 
| 
atcaleb@558
 | 
  1203     npc.class = class_token
 | 
| 
MMOSimca@584
 | 
  1204     
 | 
| 
MMOSimca@584
 | 
  1205     -- Can't do this in instances now, at least using the current method of putting a unit on a tooltip
 | 
| 
MMOSimca@585
 | 
  1206     if false then
 | 
| 
MMOSimca@584
 | 
  1207         npc.faction = UnitFactionStanding("target")
 | 
| 
MMOSimca@584
 | 
  1208     end
 | 
| 
MMOSimca@584
 | 
  1209     
 | 
| 
atcaleb@558
 | 
  1210     npc.genders = npc.genders or {}
 | 
| 
atcaleb@558
 | 
  1211     npc.genders[private.GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true
 | 
| 
atcaleb@558
 | 
  1212     npc.is_pvp = _G.UnitIsPVP("target") and true or nil
 | 
| 
atcaleb@558
 | 
  1213     npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), private.REACTION_NAMES[_G.UnitReaction("player", "target")])
 | 
| 
atcaleb@558
 | 
  1214 
 | 
| 
atcaleb@558
 | 
  1215     local encounter_data = npc:EncounterData(InstanceDifficultyToken()).stats
 | 
| 
atcaleb@558
 | 
  1216     local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
 | 
| 
atcaleb@558
 | 
  1217     local level_data = encounter_data[npc_level]
 | 
| 
atcaleb@558
 | 
  1218 
 | 
| 
atcaleb@558
 | 
  1219     if not level_data then
 | 
| 
atcaleb@558
 | 
  1220         level_data = {}
 | 
| 
atcaleb@558
 | 
  1221         encounter_data[npc_level] = level_data
 | 
| 
atcaleb@558
 | 
  1222     end
 | 
| 
MMOSimca@583
 | 
  1223     
 | 
| 
MMOSimca@583
 | 
  1224     -- Can't do this in instances now
 | 
| 
MMOSimca@583
 | 
  1225     if not III() then
 | 
| 
MMOSimca@583
 | 
  1226         level_data.max_health = level_data.max_health or _G.UnitHealthMax("target")
 | 
| 
MMOSimca@583
 | 
  1227 
 | 
| 
MMOSimca@583
 | 
  1228         -- May not capture as much data as it could, since the API changed in Legion to report multiple types of power
 | 
| 
MMOSimca@583
 | 
  1229         if not level_data.power then
 | 
| 
MMOSimca@583
 | 
  1230             local max_power = _G.UnitPowerMax("target")
 | 
| 
MMOSimca@583
 | 
  1231 
 | 
| 
MMOSimca@583
 | 
  1232             if max_power > 0 then
 | 
| 
MMOSimca@583
 | 
  1233                 local power_type = _G.UnitPowerType("target")
 | 
| 
MMOSimca@583
 | 
  1234                 level_data.power = ("%s:%d"):format(private.POWER_TYPE_NAMES[tostring(power_type)] or power_type, max_power)
 | 
| 
MMOSimca@583
 | 
  1235             end
 | 
| 
jcallahan@118
 | 
  1236         end
 | 
| 
jcallahan@118
 | 
  1237     end
 | 
| 
atcaleb@558
 | 
  1238     name_to_id_map[_G.UnitName("target")] = unit_idnum
 | 
| 
atcaleb@558
 | 
  1239     return npc, unit_idnum
 | 
| 
atcaleb@558
 | 
  1240 end
 | 
| 
jcallahan@118
 | 
  1241 
 | 
| 
jcallahan@118
 | 
  1242 
 | 
| 
jcallahan@113
 | 
  1243 do
 | 
| 
jcallahan@113
 | 
  1244     local COORD_MAX = 5
 | 
| 
jcallahan@0
 | 
  1245 
 | 
| 
jcallahan@113
 | 
  1246     function WDP:UpdateTargetLocation()
 | 
| 
catherton@480
 | 
  1247         if currently_drunk or not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or (_G.UnitIsTapDenied("target") and not _G.UnitIsDead("target")) then
 | 
| 
jcallahan@2
 | 
  1248             return
 | 
| 
jcallahan@2
 | 
  1249         end
 | 
| 
jcallahan@113
 | 
  1250 
 | 
| 
jcallahan@113
 | 
  1251         for index = 1, 4 do
 | 
| 
jcallahan@113
 | 
  1252             if not _G.CheckInteractDistance("target", index) then
 | 
| 
jcallahan@113
 | 
  1253                 return
 | 
| 
jcallahan@113
 | 
  1254             end
 | 
| 
jcallahan@113
 | 
  1255         end
 | 
| 
jcallahan@215
 | 
  1256         local npc = TargetedNPC()
 | 
| 
jcallahan@113
 | 
  1257 
 | 
| 
jcallahan@113
 | 
  1258         if not npc then
 | 
| 
jcallahan@113
 | 
  1259             return
 | 
| 
jcallahan@113
 | 
  1260         end
 | 
| 
jcallahan@113
 | 
  1261         local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
 | 
| 
MMOSimca@328
 | 
  1262         if not (zone_name and area_id and x and y and map_level) then
 | 
| 
mmosimca@508
 | 
  1263             if not (_G.IsInInstance()) then
 | 
| 
mmosimca@508
 | 
  1264                 Debug("UpdateTargetLocation: Missing current location data - %s, %s, %s, %s, %s.", tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
 | 
| 
mmosimca@508
 | 
  1265             end
 | 
| 
MMOSimca@328
 | 
  1266             return
 | 
| 
MMOSimca@328
 | 
  1267         end
 | 
| 
jcallahan@248
 | 
  1268         local npc_data = npc:EncounterData(difficulty_token).stats[("level_%d"):format(_G.UnitLevel("target"))]
 | 
| 
jcallahan@113
 | 
  1269         local zone_token = ("%s:%d"):format(zone_name, area_id)
 | 
| 
jcallahan@118
 | 
  1270         npc_data.locations = npc_data.locations or {} -- TODO: Fix this. It is broken. Possibly something to do with the timed updates.
 | 
| 
jcallahan@113
 | 
  1271 
 | 
| 
jcallahan@113
 | 
  1272         local zone_data = npc_data.locations[zone_token]
 | 
| 
jcallahan@113
 | 
  1273 
 | 
| 
jcallahan@113
 | 
  1274         if not zone_data then
 | 
| 
jcallahan@113
 | 
  1275             zone_data = {}
 | 
| 
jcallahan@113
 | 
  1276             npc_data.locations[zone_token] = zone_data
 | 
| 
jcallahan@113
 | 
  1277         end
 | 
| 
jcallahan@113
 | 
  1278 
 | 
| 
jcallahan@113
 | 
  1279         for location_token in pairs(zone_data) do
 | 
| 
jcallahan@113
 | 
  1280             local loc_level, loc_x, loc_y = (":"):split(location_token)
 | 
| 
jcallahan@113
 | 
  1281             loc_level = tonumber(loc_level)
 | 
| 
jcallahan@113
 | 
  1282 
 | 
| 
jcallahan@113
 | 
  1283             if map_level == loc_level and math.abs(x - loc_x) <= COORD_MAX and math.abs(y - loc_y) <= COORD_MAX then
 | 
| 
jcallahan@113
 | 
  1284                 return
 | 
| 
jcallahan@113
 | 
  1285             end
 | 
| 
jcallahan@113
 | 
  1286         end
 | 
| 
jcallahan@141
 | 
  1287         zone_data[("%d:%d:%d"):format(map_level, x, y)] = true
 | 
| 
jcallahan@2
 | 
  1288     end
 | 
| 
jcallahan@113
 | 
  1289 end -- do-block
 | 
| 
jcallahan@2
 | 
  1290 
 | 
| 
jcallahan@118
 | 
  1291 
 | 
| 
MMOSimca@412
 | 
  1292 function WDP:HandleBadChatLootData(...)
 | 
| 
MMOSimca@398
 | 
  1293     ClearChatLootData()
 | 
| 
MMOSimca@398
 | 
  1294 end
 | 
| 
MMOSimca@398
 | 
  1295 
 | 
| 
MMOSimca@398
 | 
  1296 
 | 
| 
MMOSimca@420
 | 
  1297 -- EVENT HANDLERS -----------------------------------------------------
 | 
| 
MMOSimca@420
 | 
  1298 
 | 
| 
MMOSimca@436
 | 
  1299 -- This function (and the following function) are to stop 'HandleItemUse' from triggering when you put an item that would normally be opened into the bank, guild bank, etc.
 | 
| 
MMOSimca@436
 | 
  1300 function WDP:StopChatLootRecording(event_name)
 | 
| 
MMOSimca@436
 | 
  1301     if not block_chat_loot_data then
 | 
| 
MMOSimca@439
 | 
  1302         Debug("%s: Pausing chat-based loot recording.", event_name)
 | 
| 
MMOSimca@436
 | 
  1303         ClearChatLootData()
 | 
| 
MMOSimca@436
 | 
  1304         block_chat_loot_data = true
 | 
| 
MMOSimca@436
 | 
  1305     end
 | 
| 
MMOSimca@436
 | 
  1306 end
 | 
| 
MMOSimca@436
 | 
  1307 
 | 
| 
MMOSimca@436
 | 
  1308 
 | 
| 
MMOSimca@436
 | 
  1309 function WDP:ResumeChatLootRecording(event_name)
 | 
| 
MMOSimca@436
 | 
  1310     if block_chat_loot_data then
 | 
| 
MMOSimca@439
 | 
  1311         Debug("%s: Resuming chat-based loot recording.", event_name)
 | 
| 
MMOSimca@436
 | 
  1312         block_chat_loot_data = false
 | 
| 
MMOSimca@436
 | 
  1313     end
 | 
| 
MMOSimca@436
 | 
  1314 end
 | 
| 
MMOSimca@436
 | 
  1315 
 | 
| 
MMOSimca@436
 | 
  1316 
 | 
| 
MMOSimca@408
 | 
  1317 -- 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.
 | 
| 
MMOSimca@408
 | 
  1318 function WDP:BONUS_ROLL_RESULT(event_name)
 | 
| 
MMOSimca@408
 | 
  1319     Debug("%s: Bonus roll detected; stopping loot recording for this boss to avoid recording bonus loot.", event_name)
 | 
| 
MMOSimca@408
 | 
  1320     ClearKilledBossID()
 | 
| 
MMOSimca@408
 | 
  1321     ClearLootToastContainerID()
 | 
| 
MMOSimca@408
 | 
  1322 end
 | 
| 
MMOSimca@408
 | 
  1323 
 | 
| 
MMOSimca@408
 | 
  1324 
 | 
| 
atcaleb@573
 | 
  1325 -- Store all known killed NPCs during an island in a table
 | 
| 
atcaleb@573
 | 
  1326 function WDP:ISLAND_AZERITE_GAIN(event_name, amount, gained_by_player, faction_index, gained_by, gained_from)
 | 
| 
atcaleb@573
 | 
  1327     -- Exit now if GUID is not for an NPC
 | 
| 
atcaleb@573
 | 
  1328     local unit_type, unit_id = ParseGUID(gained_from)
 | 
| 
atcaleb@573
 | 
  1329     if not UnitTypeIsNPC(unit_type) then
 | 
| 
atcaleb@573
 | 
  1330         return
 | 
| 
atcaleb@573
 | 
  1331     end
 | 
| 
atcaleb@573
 | 
  1332     
 | 
| 
atcaleb@573
 | 
  1333     -- Otherwise, store the NPC ID in the island kill table (if it already exists there, increment its count by 1)
 | 
| 
atcaleb@573
 | 
  1334     Debug("%s: Recording killed island NPC with ID #%d.", event_name, unit_id)
 | 
| 
atcaleb@573
 | 
  1335     if killed_npcs_in_island[unit_id] then
 | 
| 
atcaleb@573
 | 
  1336         killed_npcs_in_island[unit_id] = killed_npcs_in_island[unit_id] + 1
 | 
| 
atcaleb@573
 | 
  1337     else
 | 
| 
atcaleb@573
 | 
  1338         killed_npcs_in_island[unit_id] = 1
 | 
| 
atcaleb@573
 | 
  1339     end
 | 
| 
atcaleb@573
 | 
  1340 end
 | 
| 
atcaleb@573
 | 
  1341 
 | 
| 
atcaleb@573
 | 
  1342 
 | 
| 
atcaleb@573
 | 
  1343 -- Start chat loot timer for NPCs (and store general island information)
 | 
| 
atcaleb@573
 | 
  1344 function WDP:ISLAND_COMPLETED(event_name)
 | 
| 
atcaleb@573
 | 
  1345     island_difficulty_token = InstanceDifficultyToken()
 | 
| 
atcaleb@573
 | 
  1346 
 | 
| 
atcaleb@573
 | 
  1347     Debug("%s: Beginning chat-based loot timer for Island Expedition rewards.", event_name, item_id)
 | 
| 
atcaleb@573
 | 
  1348     chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
 | 
| 
atcaleb@573
 | 
  1349     chat_loot_data.category = AF.NPC
 | 
| 
atcaleb@573
 | 
  1350     chat_loot_data.identifier = 0
 | 
| 
atcaleb@573
 | 
  1351 end
 | 
| 
atcaleb@573
 | 
  1352 
 | 
| 
atcaleb@573
 | 
  1353 
 | 
| 
jcallahan@90
 | 
  1354 function WDP:BLACK_MARKET_ITEM_UPDATE(event_name)
 | 
| 
jcallahan@243
 | 
  1355     if not ALLOWED_LOCALES[CLIENT_LOCALE] then
 | 
| 
jcallahan@243
 | 
  1356         return
 | 
| 
jcallahan@243
 | 
  1357     end
 | 
| 
jcallahan@282
 | 
  1358     local num_items = _G.C_BlackMarket.GetNumItems() or 0
 | 
| 
jcallahan@56
 | 
  1359 
 | 
| 
jcallahan@56
 | 
  1360     for index = 1, num_items do
 | 
| 
jcallahan@56
 | 
  1361         local name, texture, quantity, item_type, is_usable, level, level_type, seller_name, min_bid, min_increment, current_bid, has_high_bid, num_bids, time_left, item_link, market_id = _G.C_BlackMarket.GetItemInfoByIndex(index);
 | 
| 
jcallahan@56
 | 
  1362 
 | 
| 
jcallahan@56
 | 
  1363         if item_link then
 | 
| 
jcallahan@56
 | 
  1364             DBEntry("items", ItemLinkToID(item_link)).black_market = seller_name or "UNKNOWN"
 | 
| 
jcallahan@56
 | 
  1365         end
 | 
| 
jcallahan@56
 | 
  1366     end
 | 
| 
jcallahan@56
 | 
  1367 end
 | 
| 
jcallahan@56
 | 
  1368 
 | 
| 
jcallahan@56
 | 
  1369 
 | 
| 
jcallahan@298
 | 
  1370 local function UpdateUnitPet(unit_guid, unit_id)
 | 
| 
jcallahan@246
 | 
  1371     local current_pet_guid = group_owner_guids_to_pet_guids[unit_guid]
 | 
| 
jcallahan@246
 | 
  1372 
 | 
| 
jcallahan@246
 | 
  1373     if current_pet_guid then
 | 
| 
jcallahan@246
 | 
  1374         group_owner_guids_to_pet_guids[unit_guid] = nil
 | 
| 
jcallahan@246
 | 
  1375         group_pet_guids[current_pet_guid] = nil
 | 
| 
jcallahan@246
 | 
  1376     end
 | 
| 
jcallahan@246
 | 
  1377     local pet_guid = _G.UnitGUID(unit_id .. "pet")
 | 
| 
jcallahan@246
 | 
  1378 
 | 
| 
jcallahan@246
 | 
  1379     if pet_guid then
 | 
| 
jcallahan@296
 | 
  1380         group_owner_guids_to_pet_guids[unit_guid] = pet_guid
 | 
| 
jcallahan@246
 | 
  1381         group_pet_guids[pet_guid] = true
 | 
| 
jcallahan@246
 | 
  1382     end
 | 
| 
jcallahan@246
 | 
  1383 end
 | 
| 
jcallahan@246
 | 
  1384 
 | 
| 
jcallahan@246
 | 
  1385 
 | 
| 
jcallahan@298
 | 
  1386 function WDP:GROUP_ROSTER_UPDATE(event_name)
 | 
| 
jcallahan@298
 | 
  1387     local is_raid = _G.IsInRaid()
 | 
| 
jcallahan@298
 | 
  1388     local unit_type = is_raid and "raid" or "party"
 | 
| 
jcallahan@298
 | 
  1389     local group_size = is_raid and _G.GetNumGroupMembers() or _G.GetNumSubgroupMembers()
 | 
| 
jcallahan@298
 | 
  1390 
 | 
| 
jcallahan@299
 | 
  1391     table.wipe(group_member_guids)
 | 
| 
jcallahan@298
 | 
  1392 
 | 
| 
jcallahan@298
 | 
  1393     for index = 1, group_size do
 | 
| 
jcallahan@298
 | 
  1394         local unit_id = unit_type .. index
 | 
| 
jcallahan@298
 | 
  1395         local unit_guid = _G.UnitGUID(unit_id)
 | 
| 
jcallahan@298
 | 
  1396 
 | 
| 
jcallahan@299
 | 
  1397         group_member_guids[unit_guid] = true
 | 
| 
jcallahan@298
 | 
  1398         UpdateUnitPet(unit_guid, unit_id)
 | 
| 
jcallahan@298
 | 
  1399     end
 | 
| 
jcallahan@299
 | 
  1400     group_member_guids[PLAYER_GUID] = true
 | 
| 
jcallahan@298
 | 
  1401 end
 | 
| 
jcallahan@298
 | 
  1402 
 | 
| 
jcallahan@298
 | 
  1403 
 | 
| 
jcallahan@298
 | 
  1404 function WDP:UNIT_PET(event_name, unit_id)
 | 
| 
jcallahan@298
 | 
  1405     UpdateUnitPet(_G.UnitGUID(unit_id), unit_id)
 | 
| 
jcallahan@298
 | 
  1406 end
 | 
| 
jcallahan@298
 | 
  1407 
 | 
| 
jcallahan@298
 | 
  1408 
 | 
| 
MMOSimca@375
 | 
  1409 function WDP:SHOW_LOOT_TOAST(event_name, loot_type, item_link, quantity, spec_ID, sex_ID, is_personal, loot_source)
 | 
| 
jcallahan@312
 | 
  1410     if not loot_type or (loot_type ~= "item" and loot_type ~= "money" and loot_type ~= "currency") then
 | 
| 
jcallahan@306
 | 
  1411         Debug("%s: loot_type is %s. Item link is %s, and quantity is %d.", event_name, loot_type, item_link, quantity)
 | 
| 
jcallahan@306
 | 
  1412         return
 | 
| 
jcallahan@306
 | 
  1413     end
 | 
| 
MMOSimca@372
 | 
  1414 
 | 
| 
MMOSimca@372
 | 
  1415     -- Need information on the most recent args, so using this complete debug statement for now
 | 
| 
MMOSimca@375
 | 
  1416     Debug("%s: loot_type: %s, item_link: %s, quantity: %s, spec_ID: %s, sex_ID: %s, is_personal: %s, loot_source: %s", event_name, loot_type, item_link, quantity, spec_ID, sex_ID, is_personal, loot_source)
 | 
| 
MMOSimca@372
 | 
  1417 
 | 
| 
MMOSimca@355
 | 
  1418     -- Handle Garrison cache specially
 | 
| 
MMOSimca@422
 | 
  1419     if loot_source and (loot_source == LOOT_SOURCE_ID_GARRISON_CACHE) and last_garrison_cache_object_id then
 | 
| 
MMOSimca@355
 | 
  1420         -- Record location data for cache
 | 
| 
MMOSimca@355
 | 
  1421         UpdateDBEntryLocation("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
 | 
| 
MMOSimca@355
 | 
  1422 
 | 
| 
MMOSimca@355
 | 
  1423         -- Add drop data
 | 
| 
mmosimca@496
 | 
  1424         local currency_id = CurrencyLinkToID(item_link)
 | 
| 
mmosimca@496
 | 
  1425         if currency_id and currency_id ~= 0 then
 | 
| 
MMOSimca@355
 | 
  1426             -- Check for top level object data
 | 
| 
MMOSimca@355
 | 
  1427             local object_entry = DBEntry("objects", ("OPENING:%d"):format(last_garrison_cache_object_id))
 | 
| 
MMOSimca@355
 | 
  1428             local difficulty_token = InstanceDifficultyToken()
 | 
| 
MMOSimca@355
 | 
  1429             if object_entry[difficulty_token] then
 | 
| 
MMOSimca@355
 | 
  1430                 -- Increment loot count
 | 
| 
MMOSimca@355
 | 
  1431                 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
 | 
| 
MMOSimca@355
 | 
  1432 
 | 
| 
mmosimca@496
 | 
  1433                 Debug("%s: %d X %d", event_name, currency_id, quantity)
 | 
| 
MMOSimca@355
 | 
  1434                 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
 | 
| 
mmosimca@496
 | 
  1435                 table.insert(object_entry[difficulty_token]["opening"], ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
MMOSimca@355
 | 
  1436             else
 | 
| 
MMOSimca@355
 | 
  1437                 Debug("%s: When handling the Garrison cache, the top level loot data was missing for objectID %d.", event_name, last_garrison_cache_object_id)
 | 
| 
MMOSimca@355
 | 
  1438             end
 | 
| 
MMOSimca@355
 | 
  1439         else
 | 
| 
mmosimca@496
 | 
  1440             Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
 | 
| 
MMOSimca@355
 | 
  1441         end
 | 
| 
catherton@465
 | 
  1442 
 | 
| 
MMOSimca@431
 | 
  1443         -- Wipe object ID until future mouseover
 | 
| 
MMOSimca@431
 | 
  1444         last_garrison_cache_object_id = nil
 | 
| 
MMOSimca@387
 | 
  1445     elseif raid_boss_id then
 | 
| 
MMOSimca@427
 | 
  1446         local npc = NPCEntry(raid_boss_id)
 | 
| 
MMOSimca@427
 | 
  1447         if npc then
 | 
| 
MMOSimca@427
 | 
  1448             local loot_label = "drops"
 | 
| 
MMOSimca@427
 | 
  1449             local encounter_data = npc:EncounterData(InstanceDifficultyToken())
 | 
| 
MMOSimca@427
 | 
  1450             encounter_data[loot_label] = encounter_data[loot_label] or {}
 | 
| 
MMOSimca@427
 | 
  1451             encounter_data.loot_counts = encounter_data.loot_counts or {}
 | 
| 
MMOSimca@427
 | 
  1452 
 | 
| 
MMOSimca@427
 | 
  1453             if loot_type == "item" then
 | 
| 
MMOSimca@427
 | 
  1454                 local item_id = ItemLinkToID(item_link)
 | 
| 
MMOSimca@427
 | 
  1455                 if item_id then
 | 
| 
MMOSimca@427
 | 
  1456                     Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
 | 
| 
MMOSimca@427
 | 
  1457                     RecordItemData(item_id, item_link, true)
 | 
| 
MMOSimca@427
 | 
  1458                     table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
 | 
| 
MMOSimca@427
 | 
  1459                 else
 | 
| 
MMOSimca@427
 | 
  1460                     Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
 | 
| 
MMOSimca@427
 | 
  1461                     return
 | 
| 
MMOSimca@427
 | 
  1462                 end
 | 
| 
MMOSimca@427
 | 
  1463             elseif loot_type == "money" then
 | 
| 
MMOSimca@427
 | 
  1464                 Debug("%s: money X %d", event_name, quantity)
 | 
| 
MMOSimca@427
 | 
  1465                 table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
 | 
| 
MMOSimca@427
 | 
  1466             elseif loot_type == "currency" then
 | 
| 
mmosimca@496
 | 
  1467                 local currency_id = CurrencyLinkToID(item_link)
 | 
| 
mmosimca@496
 | 
  1468                 if currency_id and currency_id ~= 0 then
 | 
| 
mmosimca@496
 | 
  1469                     Debug("%s: %d X %d", event_name, currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  1470                     table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
MMOSimca@427
 | 
  1471                 else
 | 
| 
mmosimca@496
 | 
  1472                     Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
 | 
| 
MMOSimca@427
 | 
  1473                     return
 | 
| 
MMOSimca@427
 | 
  1474                 end
 | 
| 
jcallahan@312
 | 
  1475             end
 | 
| 
jcallahan@317
 | 
  1476 
 | 
| 
MMOSimca@427
 | 
  1477             if not boss_loot_toasting[raid_boss_id] then
 | 
| 
MMOSimca@427
 | 
  1478                 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
 | 
| 
MMOSimca@427
 | 
  1479                 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
 | 
| 
jcallahan@312
 | 
  1480             end
 | 
| 
jcallahan@312
 | 
  1481         end
 | 
| 
MMOSimca@387
 | 
  1482     elseif loot_toast_container_id then
 | 
| 
jcallahan@305
 | 
  1483         InitializeCurrentLoot()
 | 
| 
jcallahan@305
 | 
  1484 
 | 
| 
jcallahan@306
 | 
  1485         -- Fake the loot characteristics to match that of an actual container item
 | 
| 
MMOSimca@387
 | 
  1486         current_loot.identifier = loot_toast_container_id
 | 
| 
jcallahan@306
 | 
  1487         current_loot.label = "contains"
 | 
| 
jcallahan@306
 | 
  1488         current_loot.target_type = AF.ITEM
 | 
| 
jcallahan@306
 | 
  1489 
 | 
| 
MMOSimca@387
 | 
  1490         current_loot.sources[loot_toast_container_id] = current_loot.sources[loot_toast_container_id] or {}
 | 
| 
jcallahan@312
 | 
  1491 
 | 
| 
jcallahan@301
 | 
  1492         if loot_type == "item" then
 | 
| 
jcallahan@312
 | 
  1493             local item_id = ItemLinkToID(item_link)
 | 
| 
jcallahan@312
 | 
  1494             if item_id then
 | 
| 
jcallahan@312
 | 
  1495                 Debug("%s: %s X %d (%d)", event_name, item_link, quantity, item_id)
 | 
| 
MMOSimca@340
 | 
  1496                 RecordItemData(item_id, item_link, true)
 | 
| 
MMOSimca@387
 | 
  1497                 current_loot.sources[loot_toast_container_id][item_id] = (current_loot.sources[loot_toast_container_id][item_id] or 0) + quantity
 | 
| 
jcallahan@312
 | 
  1498             else
 | 
| 
jcallahan@301
 | 
  1499                 Debug("%s: ItemID is nil, from item link %s", event_name, item_link)
 | 
| 
jcallahan@312
 | 
  1500                 current_loot = nil
 | 
| 
jcallahan@301
 | 
  1501                 return
 | 
| 
jcallahan@301
 | 
  1502             end
 | 
| 
jcallahan@301
 | 
  1503         elseif loot_type == "money" then
 | 
| 
jcallahan@312
 | 
  1504             Debug("%s: money X %d", event_name, quantity)
 | 
| 
MMOSimca@387
 | 
  1505             current_loot.sources[loot_toast_container_id]["money"] = (current_loot.sources[loot_toast_container_id]["money"] or 0) + quantity
 | 
| 
jcallahan@312
 | 
  1506         elseif loot_type == "currency" then
 | 
| 
mmosimca@496
 | 
  1507             local currency_id = CurrencyLinkToID(item_link)
 | 
| 
mmosimca@496
 | 
  1508             if currency_id and currency_id ~= 0 then
 | 
| 
mmosimca@496
 | 
  1509                 Debug("%s: %d X %d", event_name, currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  1510                 local currency_token = ("currency:%d"):format(currency_id)
 | 
| 
MMOSimca@387
 | 
  1511                 current_loot.sources[loot_toast_container_id][currency_token] = (current_loot.sources[loot_toast_container_id][currency_token] or 0) + quantity
 | 
| 
jcallahan@312
 | 
  1512             else
 | 
| 
mmosimca@496
 | 
  1513                 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
 | 
| 
jcallahan@312
 | 
  1514                 current_loot = nil
 | 
| 
jcallahan@312
 | 
  1515                 return
 | 
| 
jcallahan@312
 | 
  1516             end
 | 
| 
jcallahan@301
 | 
  1517         end
 | 
| 
jcallahan@312
 | 
  1518 
 | 
| 
jcallahan@301
 | 
  1519         GenericLootUpdate("items")
 | 
| 
jcallahan@301
 | 
  1520         current_loot = nil
 | 
| 
MMOSimca@387
 | 
  1521         container_loot_toasting = true -- Do not count further loots until timer expires or another container is opened
 | 
| 
atcaleb@573
 | 
  1522     elseif loot_source and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
 | 
| 
MMOSimca@444
 | 
  1523         -- Handle currency loot toasts for chat-based loot (we do this instead of reading currency chat messages because the chat messages are very delayed)
 | 
| 
MMOSimca@444
 | 
  1524         if loot_type == "currency" then
 | 
| 
mmosimca@496
 | 
  1525             local currency_id = CurrencyLinkToID(item_link)
 | 
| 
mmosimca@496
 | 
  1526             if currency_id and currency_id ~= 0 then
 | 
| 
MMOSimca@444
 | 
  1527                 -- Verify that we're still assigning data to the right items
 | 
| 
atcaleb@573
 | 
  1528                 if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
 | 
| 
mmosimca@496
 | 
  1529                     Debug("%s: Captured currency for chat-based loot recording. %d X %d", event_name, currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  1530                     local currency_token = ("currency:%d"):format(currency_id)
 | 
| 
MMOSimca@444
 | 
  1531                     chat_loot_data.loot = chat_loot_data.loot or {}
 | 
| 
MMOSimca@444
 | 
  1532                     chat_loot_data.loot[currency_token] = (chat_loot_data.loot[currency_token] or 0) + quantity
 | 
| 
MMOSimca@444
 | 
  1533                 else -- If not, cancel the timer and wipe the loot table early
 | 
| 
MMOSimca@444
 | 
  1534                     Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
 | 
| 
MMOSimca@444
 | 
  1535                     ClearChatLootData()
 | 
| 
MMOSimca@444
 | 
  1536                 end
 | 
| 
MMOSimca@444
 | 
  1537             else
 | 
| 
mmosimca@496
 | 
  1538                 Debug("%s: Currency ID is nil or 0, from currency link %s", event_name, item_link)
 | 
| 
MMOSimca@444
 | 
  1539             end
 | 
| 
MMOSimca@444
 | 
  1540         -- Handle money loot toasts for chat-based loot (we do this instead of reading money chat messages because the chat messages are very delayed)
 | 
| 
MMOSimca@444
 | 
  1541         elseif loot_type == "money" then
 | 
| 
MMOSimca@424
 | 
  1542             -- Verify that we're still assigning data to the right items
 | 
| 
atcaleb@573
 | 
  1543             if chat_loot_data.category == AF.ITEM and chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
 | 
| 
MMOSimca@444
 | 
  1544                 Debug("%s: Captured money for chat-based loot recording. money X %d", event_name, quantity)
 | 
| 
MMOSimca@435
 | 
  1545                 chat_loot_data.loot = chat_loot_data.loot or {}
 | 
| 
MMOSimca@444
 | 
  1546                 chat_loot_data.loot["money"] = (chat_loot_data.loot["money"] or 0) + quantity
 | 
| 
MMOSimca@424
 | 
  1547             else -- If not, cancel the timer and wipe the loot table early
 | 
| 
MMOSimca@424
 | 
  1548                 Debug("%s: Canceled chat-based loot recording because we would have assigned the wrong loot!", event_name)
 | 
| 
MMOSimca@424
 | 
  1549                 ClearChatLootData()
 | 
| 
MMOSimca@424
 | 
  1550             end
 | 
| 
MMOSimca@424
 | 
  1551         end
 | 
| 
jcallahan@301
 | 
  1552     else
 | 
| 
jcallahan@307
 | 
  1553         Debug("%s: NPC and Container are nil, storing loot toast data for 5 seconds.", event_name)
 | 
| 
jcallahan@307
 | 
  1554 
 | 
| 
jcallahan@307
 | 
  1555         loot_toast_data = loot_toast_data or {}
 | 
| 
jcallahan@312
 | 
  1556         loot_toast_data[#loot_toast_data + 1] = { loot_type, item_link, quantity }
 | 
| 
jcallahan@307
 | 
  1557 
 | 
| 
MMOSimca@340
 | 
  1558         local item_id = ItemLinkToID(item_link)
 | 
| 
MMOSimca@340
 | 
  1559         if item_id then
 | 
| 
MMOSimca@340
 | 
  1560             RecordItemData(item_id, item_link, true)
 | 
| 
MMOSimca@340
 | 
  1561         end
 | 
| 
MMOSimca@340
 | 
  1562 
 | 
| 
MMOSimca@383
 | 
  1563         loot_toast_data_timer_handle = C_Timer.NewTimer(5, ClearLootToastData)
 | 
| 
jcallahan@178
 | 
  1564     end
 | 
| 
jcallahan@178
 | 
  1565 end
 | 
| 
jcallahan@178
 | 
  1566 
 | 
| 
jcallahan@178
 | 
  1567 
 | 
| 
jcallahan@179
 | 
  1568 do
 | 
| 
MMOSimca@388
 | 
  1569     local CHAT_MSG_CURRENCY_UPDATE_FUNCS = {
 | 
| 
mmosimca@496
 | 
  1570         [AF.NPC] = function(currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  1571             Debug("CHAT_MSG_CURRENCY: AF.NPC currency:%d (%d)", currency_id, quantity)
 | 
| 
MMOSimca@388
 | 
  1572         end,
 | 
| 
mmosimca@496
 | 
  1573         [AF.ZONE] = function(currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  1574             Debug("CHAT_MSG_CURRENCY: AF.ZONE currency:%d (%d)", currency_id, quantity)
 | 
| 
MMOSimca@388
 | 
  1575             InitializeCurrentLoot()
 | 
| 
mmosimca@496
 | 
  1576             current_loot.list[1] = ("currency:%d:%d"):format(quantity, currency_id)
 | 
| 
MMOSimca@388
 | 
  1577             GenericLootUpdate("zones")
 | 
| 
MMOSimca@388
 | 
  1578             current_loot = nil
 | 
| 
MMOSimca@388
 | 
  1579         end,
 | 
| 
MMOSimca@388
 | 
  1580     }
 | 
| 
MMOSimca@388
 | 
  1581 
 | 
| 
MMOSimca@388
 | 
  1582 
 | 
| 
MMOSimca@388
 | 
  1583     function WDP:CHAT_MSG_CURRENCY(event_name, message)
 | 
| 
MMOSimca@388
 | 
  1584         local category
 | 
| 
MMOSimca@388
 | 
  1585 
 | 
| 
MMOSimca@388
 | 
  1586         local currency_link, quantity = deformat(message, _G.CURRENCY_GAINED_MULTIPLE)
 | 
| 
MMOSimca@388
 | 
  1587         if not currency_link then
 | 
| 
MMOSimca@388
 | 
  1588             quantity, currency_link = 1, deformat(message, _G.CURRENCY_GAINED)
 | 
| 
MMOSimca@388
 | 
  1589         end
 | 
| 
mmosimca@496
 | 
  1590         local currency_id = CurrencyLinkToID(currency_link)
 | 
| 
mmosimca@496
 | 
  1591 
 | 
| 
mmosimca@496
 | 
  1592         if not currency_id or currency_id == 0 then
 | 
| 
MMOSimca@388
 | 
  1593             return
 | 
| 
MMOSimca@388
 | 
  1594         end
 | 
| 
MMOSimca@388
 | 
  1595 
 | 
| 
MMOSimca@388
 | 
  1596         -- Set update category
 | 
| 
MMOSimca@388
 | 
  1597         if current_action.spell_label == "FISHING" then
 | 
| 
MMOSimca@388
 | 
  1598             category = AF.ZONE
 | 
| 
MMOSimca@388
 | 
  1599         elseif raid_boss_id then
 | 
| 
MMOSimca@388
 | 
  1600             category = AF.NPC
 | 
| 
MMOSimca@388
 | 
  1601         end
 | 
| 
MMOSimca@388
 | 
  1602 
 | 
| 
MMOSimca@388
 | 
  1603         -- Take action based on update category
 | 
| 
MMOSimca@388
 | 
  1604         local update_func = CHAT_MSG_CURRENCY_UPDATE_FUNCS[category]
 | 
| 
MMOSimca@388
 | 
  1605         if not category or not update_func then
 | 
| 
MMOSimca@388
 | 
  1606             return
 | 
| 
MMOSimca@388
 | 
  1607         end
 | 
| 
mmosimca@496
 | 
  1608         update_func(currency_id, quantity)
 | 
| 
MMOSimca@388
 | 
  1609     end
 | 
| 
MMOSimca@388
 | 
  1610 
 | 
| 
MMOSimca@388
 | 
  1611 
 | 
| 
jcallahan@179
 | 
  1612     local CHAT_MSG_LOOT_UPDATE_FUNCS = {
 | 
| 
atcaleb@573
 | 
  1613         -- Handle chat loot data from item containers
 | 
| 
MMOSimca@347
 | 
  1614         [AF.ITEM] = function(item_id, quantity)
 | 
| 
MMOSimca@347
 | 
  1615             -- Verify that we're still assigning data to the right items
 | 
| 
MMOSimca@435
 | 
  1616             if chat_loot_data.identifier and (private.CONTAINER_ITEM_ID_LIST[chat_loot_data.identifier] ~= nil) then
 | 
| 
MMOSimca@347
 | 
  1617                 Debug("CHAT_MSG_LOOT: AF.ITEM %d (%d)", item_id, quantity)
 | 
| 
MMOSimca@435
 | 
  1618                 chat_loot_data.loot = chat_loot_data.loot or {}
 | 
| 
MMOSimca@435
 | 
  1619                 chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
 | 
| 
MMOSimca@347
 | 
  1620             else -- If not, cancel the timer and wipe the loot table early
 | 
| 
MMOSimca@387
 | 
  1621                 Debug("CHAT_MSG_LOOT: We would have assigned the wrong loot!")
 | 
| 
MMOSimca@387
 | 
  1622                 ClearChatLootData()
 | 
| 
MMOSimca@347
 | 
  1623             end
 | 
| 
MMOSimca@347
 | 
  1624         end,
 | 
| 
atcaleb@573
 | 
  1625         -- Handle chat loot data from island expedition rewards
 | 
| 
jcallahan@179
 | 
  1626         [AF.NPC] = function(item_id, quantity)
 | 
| 
MMOSimca@345
 | 
  1627             Debug("CHAT_MSG_LOOT: AF.NPC %d (%d)", item_id, quantity)
 | 
| 
atcaleb@573
 | 
  1628             chat_loot_data.loot = chat_loot_data.loot or {}
 | 
| 
atcaleb@573
 | 
  1629             chat_loot_data.loot[item_id] = (chat_loot_data.loot[item_id] or 0) + quantity
 | 
| 
MMOSimca@345
 | 
  1630         end,
 | 
| 
atcaleb@573
 | 
  1631         -- Handle logging spells for objects
 | 
| 
MMOSimca@345
 | 
  1632         [AF.OBJECT] = function(item_id, quantity)
 | 
| 
MMOSimca@345
 | 
  1633             Debug("CHAT_MSG_LOOT: AF.OBJECT %d (%d)", item_id, quantity)
 | 
| 
MMOSimca@381
 | 
  1634             -- Check for top level object data
 | 
| 
MMOSimca@381
 | 
  1635             local object_entry = DBEntry("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[last_timber_spell_id]))
 | 
| 
MMOSimca@381
 | 
  1636             local difficulty_token = InstanceDifficultyToken()
 | 
| 
MMOSimca@381
 | 
  1637             if object_entry[difficulty_token] then
 | 
| 
MMOSimca@381
 | 
  1638                 -- Increment loot count
 | 
| 
MMOSimca@381
 | 
  1639                 object_entry[difficulty_token]["opening_count"] = (object_entry[difficulty_token]["opening_count"] or 0) + 1
 | 
| 
MMOSimca@381
 | 
  1640 
 | 
| 
MMOSimca@381
 | 
  1641                 -- Add drop data
 | 
| 
MMOSimca@381
 | 
  1642                 object_entry[difficulty_token]["opening"] = object_entry[difficulty_token]["opening"] or {}
 | 
| 
MMOSimca@381
 | 
  1643                 table.insert(object_entry[difficulty_token]["opening"], ("%d:%d"):format(item_id, quantity))
 | 
| 
MMOSimca@381
 | 
  1644             else
 | 
| 
MMOSimca@381
 | 
  1645                 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])
 | 
| 
MMOSimca@381
 | 
  1646             end
 | 
| 
jcallahan@179
 | 
  1647         end,
 | 
| 
atcaleb@573
 | 
  1648         -- Handle fishing loot table population
 | 
| 
jcallahan@179
 | 
  1649         [AF.ZONE] = function(item_id, quantity)
 | 
| 
MMOSimca@345
 | 
  1650             Debug("CHAT_MSG_LOOT: AF.ZONE %d (%d)", item_id, quantity)
 | 
| 
jcallahan@312
 | 
  1651             InitializeCurrentLoot()
 | 
| 
jcallahan@312
 | 
  1652             current_loot.list[1] = ("%d:%d"):format(item_id, quantity)
 | 
| 
jcallahan@179
 | 
  1653             GenericLootUpdate("zones")
 | 
| 
jcallahan@312
 | 
  1654             current_loot = nil
 | 
| 
jcallahan@179
 | 
  1655         end,
 | 
| 
jcallahan@179
 | 
  1656     }
 | 
| 
jcallahan@177
 | 
  1657 
 | 
| 
jcallahan@177
 | 
  1658 
 | 
| 
MMOSimca@388
 | 
  1659     function WDP:CHAT_MSG_LOOT(event_name, message)
 | 
| 
jcallahan@179
 | 
  1660         local category
 | 
| 
jcallahan@177
 | 
  1661 
 | 
| 
MMOSimca@345
 | 
  1662         local item_link, quantity = deformat(message, _G.LOOT_ITEM_PUSHED_SELF_MULTIPLE)
 | 
| 
MMOSimca@345
 | 
  1663         if not item_link then
 | 
| 
MMOSimca@345
 | 
  1664             quantity, item_link = 1, deformat(message, _G.LOOT_ITEM_PUSHED_SELF)
 | 
| 
MMOSimca@345
 | 
  1665         end
 | 
| 
MMOSimca@345
 | 
  1666         local item_id = ItemLinkToID(item_link)
 | 
| 
MMOSimca@345
 | 
  1667 
 | 
| 
MMOSimca@345
 | 
  1668         if not item_id then
 | 
| 
MMOSimca@345
 | 
  1669             return
 | 
| 
MMOSimca@345
 | 
  1670         end
 | 
| 
MMOSimca@345
 | 
  1671 
 | 
| 
MMOSimca@345
 | 
  1672         -- Set update category
 | 
| 
MMOSimca@405
 | 
  1673         if last_timber_spell_id and item_id == ITEM_ID_TIMBER then
 | 
| 
MMOSimca@345
 | 
  1674             category = AF.OBJECT
 | 
| 
atcaleb@573
 | 
  1675         -- Changed from ~= "EXTRACT_GAS" because of some occassional bad data, and, as far as I know, no benefit.
 | 
| 
MMOSimca@345
 | 
  1676         elseif current_action.spell_label == "FISHING" then
 | 
| 
jcallahan@179
 | 
  1677             category = AF.ZONE
 | 
| 
atcaleb@573
 | 
  1678         elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.NPC then
 | 
| 
jcallahan@179
 | 
  1679             category = AF.NPC
 | 
| 
atcaleb@573
 | 
  1680         elseif not raid_boss_id and chat_loot_timer_handle and chat_loot_data.category == AF.ITEM then
 | 
| 
MMOSimca@347
 | 
  1681             category = AF.ITEM
 | 
| 
jcallahan@179
 | 
  1682         end
 | 
| 
MMOSimca@345
 | 
  1683 
 | 
| 
MMOSimca@395
 | 
  1684         -- We still want to record the item's data, even if it doesn't need its drop location recorded
 | 
| 
MMOSimca@395
 | 
  1685         RecordItemData(item_id, item_link, true)
 | 
| 
MMOSimca@395
 | 
  1686 
 | 
| 
MMOSimca@345
 | 
  1687         -- Take action based on update category
 | 
| 
jcallahan@179
 | 
  1688         local update_func = CHAT_MSG_LOOT_UPDATE_FUNCS[category]
 | 
| 
atcaleb@558
 | 
  1689         if not category or not update_func or private.BLACKLISTED_ITEMS[item_id] then
 | 
| 
MMOSimca@340
 | 
  1690             return
 | 
| 
MMOSimca@340
 | 
  1691         end
 | 
| 
jcallahan@179
 | 
  1692         update_func(item_id, quantity)
 | 
| 
jcallahan@177
 | 
  1693     end
 | 
| 
MMOSimca@388
 | 
  1694 end
 | 
| 
MMOSimca@388
 | 
  1695 
 | 
| 
MMOSimca@388
 | 
  1696 
 | 
| 
jcallahan@97
 | 
  1697 function WDP:RecordQuote(event_name, message, source_name, language_name)
 | 
| 
jcallahan@112
 | 
  1698     if not ALLOWED_LOCALES[CLIENT_LOCALE] or not source_name or not name_to_id_map[source_name] or (language_name ~= "" and not languages_known[language_name]) then
 | 
| 
jcallahan@97
 | 
  1699         return
 | 
| 
jcallahan@95
 | 
  1700     end
 | 
| 
jcallahan@97
 | 
  1701     local npc = NPCEntry(name_to_id_map[source_name])
 | 
| 
jcallahan@97
 | 
  1702     npc.quotes = npc.quotes or {}
 | 
| 
jcallahan@97
 | 
  1703     npc.quotes[event_name] = npc.quotes[event_name] or {}
 | 
| 
jcallahan@97
 | 
  1704     npc.quotes[event_name][ReplaceKeywords(message)] = true
 | 
| 
jcallahan@97
 | 
  1705 end
 | 
| 
jcallahan@95
 | 
  1706 
 | 
| 
jcallahan@95
 | 
  1707 
 | 
| 
jcallahan@95
 | 
  1708 do
 | 
| 
jcallahan@40
 | 
  1709     local SOBER_MATCH = _G.DRUNK_MESSAGE_ITEM_SELF1:gsub("%%s", ".+")
 | 
| 
jcallahan@40
 | 
  1710 
 | 
| 
jcallahan@40
 | 
  1711     local DRUNK_COMPARES = {
 | 
| 
jcallahan@40
 | 
  1712         _G.DRUNK_MESSAGE_SELF2,
 | 
| 
jcallahan@40
 | 
  1713         _G.DRUNK_MESSAGE_SELF3,
 | 
| 
jcallahan@40
 | 
  1714         _G.DRUNK_MESSAGE_SELF4,
 | 
| 
jcallahan@40
 | 
  1715     }
 | 
| 
jcallahan@40
 | 
  1716 
 | 
| 
jcallahan@40
 | 
  1717     local DRUNK_MATCHES = {
 | 
| 
jcallahan@254
 | 
  1718         (_G.DRUNK_MESSAGE_SELF2:gsub("%%s", ".+")),
 | 
| 
jcallahan@254
 | 
  1719         (_G.DRUNK_MESSAGE_SELF3:gsub("%%s", ".+")),
 | 
| 
jcallahan@254
 | 
  1720         (_G.DRUNK_MESSAGE_SELF4:gsub("%%s", ".+")),
 | 
| 
jcallahan@40
 | 
  1721     }
 | 
| 
jcallahan@40
 | 
  1722 
 | 
| 
jcallahan@167
 | 
  1723     local RECIPE_MATCH = _G.ERR_LEARN_RECIPE_S:gsub("%%s", "(.*)")
 | 
| 
jcallahan@167
 | 
  1724 
 | 
| 
jcallahan@167
 | 
  1725 
 | 
| 
jcallahan@167
 | 
  1726     local function RecordDiscovery(tradeskill_name, tradeskill_index)
 | 
| 
jcallahan@167
 | 
  1727         if tradeskill_name == private.discovered_recipe_name then
 | 
| 
catherton@479
 | 
  1728             DBEntry("spells", tonumber(_G.C_TradeSkillUI.GetRecipeLink(tradeskill_index):match("^|c%x%x%x%x%x%x%x%x|H%w+:(%d+)"))).discovery = ("%d:%d"):format(private.previous_spell_id, private.profession_level)
 | 
| 
jcallahan@167
 | 
  1729 
 | 
| 
jcallahan@167
 | 
  1730             private.discovered_recipe_name = nil
 | 
| 
jcallahan@167
 | 
  1731             private.profession_level = nil
 | 
| 
jcallahan@167
 | 
  1732             private.previous_spell_id = nil
 | 
| 
jcallahan@169
 | 
  1733 
 | 
| 
jcallahan@169
 | 
  1734             return true
 | 
| 
jcallahan@167
 | 
  1735         end
 | 
| 
jcallahan@167
 | 
  1736     end
 | 
| 
jcallahan@167
 | 
  1737 
 | 
| 
jcallahan@167
 | 
  1738 
 | 
| 
jcallahan@167
 | 
  1739     local function IterativeRecordDiscovery()
 | 
| 
jcallahan@167
 | 
  1740         TradeSkillExecutePer(RecordDiscovery)
 | 
| 
jcallahan@167
 | 
  1741     end
 | 
| 
jcallahan@167
 | 
  1742 
 | 
| 
jcallahan@167
 | 
  1743 
 | 
| 
jcallahan@92
 | 
  1744     function WDP:CHAT_MSG_SYSTEM(event_name, message)
 | 
| 
mmosimca@514
 | 
  1745         -- This code no longer works, as of Patch 7.0.3, because Blizzard unified the text from quest rewards and loot to match (and now there is no way to distinguish between them)
 | 
| 
MMOSimca@532
 | 
  1746         --[[
 | 
| 
MMOSimca@532
 | 
  1747         -- Removed in Patch 7.0.3; previously used to determine if a system message was a quest reward or not
 | 
| 
MMOSimca@532
 | 
  1748         local ERR_QUEST_REWARD_ITEM_MULT_IS = _G.ERR_QUEST_REWARD_ITEM_MULT_IS or "Received %d of item: %s."
 | 
| 
MMOSimca@532
 | 
  1749         local ERR_QUEST_REWARD_ITEM_S = _G.ERR_QUEST_REWARD_ITEM_S or "Received item: %s."
 | 
| 
MMOSimca@532
 | 
  1750 
 | 
| 
catherton@472
 | 
  1751         local item_link, quantity = deformat(message, ERR_QUEST_REWARD_ITEM_MULT_IS)
 | 
| 
MMOSimca@400
 | 
  1752         if not item_link then
 | 
| 
catherton@472
 | 
  1753             quantity, item_link = 1, deformat(message, ERR_QUEST_REWARD_ITEM_S)
 | 
| 
MMOSimca@400
 | 
  1754         end
 | 
| 
MMOSimca@400
 | 
  1755         local item_id = ItemLinkToID(item_link)
 | 
| 
MMOSimca@400
 | 
  1756 
 | 
| 
mmosimca@514
 | 
  1757         if item_id then
 | 
| 
mmosimca@514
 | 
  1758             -- If it was a quest message (that we can decode), parse its link
 | 
| 
mmosimca@514
 | 
  1759             RecordItemData(item_id, item_link, true)
 | 
| 
mmosimca@514
 | 
  1760         else
 | 
| 
mmosimca@514
 | 
  1761             -- If it isn't a quest message, check the other uses of system messages
 | 
| 
MMOSimca@532
 | 
  1762         end
 | 
| 
MMOSimca@532
 | 
  1763         ]]--
 | 
| 
MMOSimca@532
 | 
  1764 
 | 
| 
MMOSimca@532
 | 
  1765         if not private.trainer_shown then
 | 
| 
MMOSimca@532
 | 
  1766             local recipe_name = message:match(RECIPE_MATCH)
 | 
| 
MMOSimca@532
 | 
  1767 
 | 
| 
MMOSimca@532
 | 
  1768             if recipe_name and private.previous_spell_id then
 | 
| 
MMOSimca@532
 | 
  1769                 local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
 | 
| 
MMOSimca@532
 | 
  1770 
 | 
| 
MMOSimca@532
 | 
  1771                 if profession_name == _G.UNKNOWN then
 | 
| 
MMOSimca@532
 | 
  1772                     return
 | 
| 
jcallahan@167
 | 
  1773                 end
 | 
| 
MMOSimca@532
 | 
  1774                 private.discovered_recipe_name = recipe_name
 | 
| 
MMOSimca@532
 | 
  1775                 private.profession_level = prof_level
 | 
| 
MMOSimca@532
 | 
  1776 
 | 
| 
MMOSimca@532
 | 
  1777                 C_Timer.After(0.2, IterativeRecordDiscovery)
 | 
| 
jcallahan@167
 | 
  1778             end
 | 
| 
MMOSimca@532
 | 
  1779         end
 | 
| 
MMOSimca@532
 | 
  1780 
 | 
| 
MMOSimca@532
 | 
  1781         if currently_drunk then
 | 
| 
MMOSimca@532
 | 
  1782             if message == _G.DRUNK_MESSAGE_SELF1 or message:match(SOBER_MATCH) then
 | 
| 
MMOSimca@532
 | 
  1783                 currently_drunk = nil
 | 
| 
MMOSimca@400
 | 
  1784             end
 | 
| 
MMOSimca@532
 | 
  1785             return
 | 
| 
MMOSimca@532
 | 
  1786         end
 | 
| 
MMOSimca@532
 | 
  1787 
 | 
| 
MMOSimca@532
 | 
  1788         for index = 1, #DRUNK_MATCHES do
 | 
| 
MMOSimca@532
 | 
  1789             if message == DRUNK_COMPARES[index] or message:match(DRUNK_MATCHES[index]) then
 | 
| 
MMOSimca@532
 | 
  1790                 currently_drunk = true
 | 
| 
MMOSimca@532
 | 
  1791                 break
 | 
| 
jcallahan@40
 | 
  1792             end
 | 
| 
jcallahan@40
 | 
  1793         end
 | 
| 
jcallahan@40
 | 
  1794     end
 | 
| 
jcallahan@40
 | 
  1795 end
 | 
| 
jcallahan@40
 | 
  1796 
 | 
| 
jcallahan@307
 | 
  1797 
 | 
| 
MMOSimca@581
 | 
  1798 function WDP:WORLD_CURSOR_TOOLTIP_UPDATE(event_name, is_shown)
 | 
| 
MMOSimca@355
 | 
  1799     if current_action.fishing_target or _G.Minimap:IsMouseOver() then
 | 
| 
jcallahan@140
 | 
  1800         return
 | 
| 
jcallahan@140
 | 
  1801     end
 | 
| 
jcallahan@140
 | 
  1802     local text = _G["GameTooltipTextLeft1"]:GetText()
 | 
| 
jcallahan@140
 | 
  1803 
 | 
| 
MMOSimca@355
 | 
  1804     -- Handle Fishing
 | 
| 
MMOSimca@355
 | 
  1805     if (current_action.spell_label == "FISHING") then
 | 
| 
MMOSimca@355
 | 
  1806         if not text or text == "Fishing Bobber" then
 | 
| 
MMOSimca@355
 | 
  1807             text = "NONE"
 | 
| 
MMOSimca@355
 | 
  1808         else
 | 
| 
MMOSimca@355
 | 
  1809             current_action.fishing_target = true
 | 
| 
MMOSimca@355
 | 
  1810         end
 | 
| 
MMOSimca@355
 | 
  1811         current_action.identifier = ("%s:%s"):format(current_action.spell_label, text)
 | 
| 
MMOSimca@355
 | 
  1812      -- Handle Garrison Cache
 | 
| 
MMOSimca@355
 | 
  1813     elseif private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text] then
 | 
| 
MMOSimca@355
 | 
  1814         last_garrison_cache_object_id = private.GARRISON_CACHE_OBJECT_NAME_TO_OBJECT_ID_MAP[text]
 | 
| 
jcallahan@140
 | 
  1815     end
 | 
| 
jcallahan@140
 | 
  1816 end
 | 
| 
jcallahan@140
 | 
  1817 
 | 
| 
jcallahan@140
 | 
  1818 
 | 
| 
jcallahan@92
 | 
  1819 function WDP:ITEM_TEXT_BEGIN(event_name)
 | 
| 
jcallahan@42
 | 
  1820     local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@42
 | 
  1821 
 | 
| 
jcallahan@42
 | 
  1822     if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT or _G.UnitName("npc") ~= _G.ItemTextGetItem() then
 | 
| 
jcallahan@42
 | 
  1823         return
 | 
| 
jcallahan@42
 | 
  1824     end
 | 
| 
jcallahan@42
 | 
  1825     UpdateDBEntryLocation("objects", unit_idnum)
 | 
| 
jcallahan@42
 | 
  1826 end
 | 
| 
jcallahan@42
 | 
  1827 
 | 
| 
jcallahan@42
 | 
  1828 
 | 
| 
jcallahan@13
 | 
  1829 do
 | 
| 
MMOSimca@343
 | 
  1830     local LOOT_OPENED_VERIFY_FUNCS = {
 | 
| 
jcallahan@324
 | 
  1831         -- Item containers can be AOE-looted in Patch 5.4.2 if the user clicks fast enough, but this verification still works as long as they both have loot.
 | 
| 
jcallahan@16
 | 
  1832         [AF.ITEM] = function()
 | 
| 
jcallahan@16
 | 
  1833             local locked_item_id
 | 
| 
jcallahan@16
 | 
  1834 
 | 
| 
jcallahan@16
 | 
  1835             for bag_index = 0, _G.NUM_BAG_FRAMES do
 | 
| 
MMOSimca@581
 | 
  1836                 for slot_index = 1, _G.C_Container.GetContainerNumSlots(bag_index) do
 | 
| 
MMOSimca@581
 | 
  1837                     local _, _, is_locked, _, _, is_lootable = _G.C_Container.GetContainerItemInfo(bag_index, slot_index)
 | 
| 
jcallahan@324
 | 
  1838 
 | 
| 
jcallahan@324
 | 
  1839                     if is_locked and is_lootable then
 | 
| 
MMOSimca@581
 | 
  1840                         locked_item_id = ItemLinkToID(_G.C_Container.GetContainerItemLink(bag_index, slot_index))
 | 
| 
jcallahan@165
 | 
  1841                         break
 | 
| 
jcallahan@16
 | 
  1842                     end
 | 
| 
jcallahan@16
 | 
  1843                 end
 | 
| 
jcallahan@165
 | 
  1844 
 | 
| 
jcallahan@165
 | 
  1845                 if locked_item_id then
 | 
| 
jcallahan@165
 | 
  1846                     break
 | 
| 
jcallahan@165
 | 
  1847                 end
 | 
| 
jcallahan@16
 | 
  1848             end
 | 
| 
jcallahan@16
 | 
  1849 
 | 
| 
MMOSimca@367
 | 
  1850             if (not current_action.spell_label == "DISENCHANT") and (not locked_item_id or (current_action.identifier and current_action.identifier ~= locked_item_id)) then
 | 
| 
jcallahan@16
 | 
  1851                 return false
 | 
| 
jcallahan@16
 | 
  1852             end
 | 
| 
jcallahan@122
 | 
  1853             current_action.identifier = locked_item_id
 | 
| 
jcallahan@16
 | 
  1854             return true
 | 
| 
jcallahan@16
 | 
  1855         end,
 | 
| 
MMOSimca@401
 | 
  1856         [AF.NPC] = function()
 | 
| 
MMOSimca@401
 | 
  1857             return not _G.IsFishingLoot()
 | 
| 
MMOSimca@401
 | 
  1858         end,
 | 
| 
MMOSimca@401
 | 
  1859         [AF.OBJECT] = function()
 | 
| 
MMOSimca@401
 | 
  1860             return not _G.IsFishingLoot()
 | 
| 
MMOSimca@401
 | 
  1861         end,
 | 
| 
jcallahan@17
 | 
  1862         [AF.ZONE] = function()
 | 
| 
jcallahan@140
 | 
  1863             current_action.zone_data = UpdateDBEntryLocation("zones", current_action.identifier)
 | 
| 
jcallahan@210
 | 
  1864             return _G.IsFishingLoot()
 | 
| 
jcallahan@17
 | 
  1865         end,
 | 
| 
jcallahan@13
 | 
  1866     }
 | 
| 
jcallahan@13
 | 
  1867 
 | 
| 
jcallahan@13
 | 
  1868 
 | 
| 
MMOSimca@343
 | 
  1869     local LOOT_OPENED_UPDATE_FUNCS = {
 | 
| 
jcallahan@16
 | 
  1870         [AF.ITEM] = function()
 | 
| 
jcallahan@28
 | 
  1871             GenericLootUpdate("items")
 | 
| 
jcallahan@28
 | 
  1872         end,
 | 
| 
jcallahan@28
 | 
  1873         [AF.NPC] = function()
 | 
| 
jcallahan@75
 | 
  1874             local difficulty_token = InstanceDifficultyToken()
 | 
| 
jcallahan@312
 | 
  1875             local loot_label = current_loot.label
 | 
| 
jcallahan@77
 | 
  1876             local source_list = {}
 | 
| 
jcallahan@75
 | 
  1877 
 | 
| 
jcallahan@131
 | 
  1878             for source_guid, loot_data in pairs(current_loot.sources) do
 | 
| 
jcallahan@331
 | 
  1879                 local _, source_id = ParseGUID(source_guid)
 | 
| 
jcallahan@75
 | 
  1880                 local npc = NPCEntry(source_id)
 | 
| 
jcallahan@75
 | 
  1881 
 | 
| 
jcallahan@75
 | 
  1882                 if npc then
 | 
| 
jcallahan@248
 | 
  1883                     local encounter_data = npc:EncounterData(difficulty_token)
 | 
| 
jcallahan@312
 | 
  1884                     encounter_data[loot_label] = encounter_data[loot_label] or {}
 | 
| 
jcallahan@75
 | 
  1885 
 | 
| 
jcallahan@78
 | 
  1886                     if not source_list[source_guid] then
 | 
| 
jcallahan@77
 | 
  1887                         encounter_data.loot_counts = encounter_data.loot_counts or {}
 | 
| 
MMOSimca@426
 | 
  1888                         encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
 | 
| 
jcallahan@312
 | 
  1889                         source_list[source_guid] = true
 | 
| 
jcallahan@77
 | 
  1890                     end
 | 
| 
jcallahan@77
 | 
  1891 
 | 
| 
jcallahan@309
 | 
  1892                     for loot_token, quantity in pairs(loot_data) do
 | 
| 
mmosimca@496
 | 
  1893                         local loot_type, currency_id = (":"):split(loot_token)
 | 
| 
mmosimca@496
 | 
  1894 
 | 
| 
mmosimca@496
 | 
  1895                         if loot_type == "currency" and currency_id then
 | 
| 
mmosimca@496
 | 
  1896                             -- Convert currency_id back into number from string
 | 
| 
mmosimca@496
 | 
  1897                             currency_id = tonumber(currency_id) or 0
 | 
| 
mmosimca@496
 | 
  1898                             if currency_id ~= 0 then
 | 
| 
mmosimca@496
 | 
  1899                                 table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
mmosimca@496
 | 
  1900                             end
 | 
| 
jcallahan@309
 | 
  1901                         elseif loot_token == "money" then
 | 
| 
jcallahan@312
 | 
  1902                             table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
 | 
| 
jcallahan@309
 | 
  1903                         else
 | 
| 
jcallahan@312
 | 
  1904                             table.insert(encounter_data[loot_label], ("%d:%d"):format(loot_token, quantity))
 | 
| 
jcallahan@309
 | 
  1905                         end
 | 
| 
jcallahan@75
 | 
  1906                     end
 | 
| 
jcallahan@75
 | 
  1907                 end
 | 
| 
jcallahan@75
 | 
  1908             end
 | 
| 
jcallahan@16
 | 
  1909         end,
 | 
| 
jcallahan@13
 | 
  1910         [AF.OBJECT] = function()
 | 
| 
jcallahan@28
 | 
  1911             GenericLootUpdate("objects", InstanceDifficultyToken())
 | 
| 
jcallahan@17
 | 
  1912         end,
 | 
| 
jcallahan@17
 | 
  1913         [AF.ZONE] = function()
 | 
| 
MMOSimca@328
 | 
  1914             if not (current_loot.map_level and current_loot.x and current_loot.y and current_loot.zone_data) then
 | 
| 
MMOSimca@328
 | 
  1915                 return
 | 
| 
MMOSimca@328
 | 
  1916             end
 | 
| 
jcallahan@141
 | 
  1917             local location_token = ("%d:%d:%d"):format(current_loot.map_level, current_loot.x, current_loot.y)
 | 
| 
jcallahan@41
 | 
  1918 
 | 
| 
jcallahan@41
 | 
  1919             -- This will start life as a boolean true.
 | 
| 
mmosimca@522
 | 
  1920             if type(current_loot.zone_data[location_token]) ~= "table" then
 | 
| 
jcallahan@131
 | 
  1921                 current_loot.zone_data[location_token] = {
 | 
| 
jcallahan@41
 | 
  1922                     drops = {}
 | 
| 
jcallahan@41
 | 
  1923                 }
 | 
| 
jcallahan@41
 | 
  1924             end
 | 
| 
jcallahan@132
 | 
  1925             local loot_count = ("%s_count"):format(current_loot.label)
 | 
| 
jcallahan@131
 | 
  1926             current_loot.zone_data[location_token][loot_count] = (current_loot.zone_data[location_token][loot_count] or 0) + 1
 | 
| 
jcallahan@41
 | 
  1927 
 | 
| 
jcallahan@131
 | 
  1928             if current_loot.sources then
 | 
| 
jcallahan@131
 | 
  1929                 for source_guid, loot_data in pairs(current_loot.sources) do
 | 
| 
jcallahan@131
 | 
  1930                     for item_id, quantity in pairs(loot_data) do
 | 
| 
jcallahan@131
 | 
  1931                         table.insert(current_loot.zone_data[location_token].drops, ("%d:%d"):format(item_id, quantity))
 | 
| 
jcallahan@131
 | 
  1932                     end
 | 
| 
jcallahan@131
 | 
  1933                 end
 | 
| 
jcallahan@131
 | 
  1934             end
 | 
| 
jcallahan@131
 | 
  1935 
 | 
| 
jcallahan@131
 | 
  1936             if #current_loot.list <= 0 then
 | 
| 
jcallahan@131
 | 
  1937                 return
 | 
| 
jcallahan@131
 | 
  1938             end
 | 
| 
jcallahan@131
 | 
  1939 
 | 
| 
jcallahan@131
 | 
  1940             for index = 1, #current_loot.list do
 | 
| 
MMOSimca@443
 | 
  1941                 table.insert(current_loot.zone_data[location_token].drops, current_loot.list[index])
 | 
| 
jcallahan@41
 | 
  1942             end
 | 
| 
jcallahan@13
 | 
  1943         end,
 | 
| 
jcallahan@13
 | 
  1944     }
 | 
| 
jcallahan@13
 | 
  1945 
 | 
| 
jcallahan@79
 | 
  1946     -- Prevent opening the same loot window multiple times from recording data multiple times.
 | 
| 
jcallahan@79
 | 
  1947     local loot_guid_registry = {}
 | 
| 
jcallahan@124
 | 
  1948 
 | 
| 
jcallahan@124
 | 
  1949 
 | 
| 
jcallahan@124
 | 
  1950     function WDP:LOOT_CLOSED(event_name)
 | 
| 
MMOSimca@398
 | 
  1951         ClearChatLootData()
 | 
| 
jcallahan@131
 | 
  1952         current_loot = nil
 | 
| 
jcallahan@131
 | 
  1953         table.wipe(current_action)
 | 
| 
jcallahan@124
 | 
  1954     end
 | 
| 
jcallahan@124
 | 
  1955 
 | 
| 
jcallahan@13
 | 
  1956 
 | 
| 
jcallahan@322
 | 
  1957     local function ExtrapolatedCurrentActionFromLootData(event_name)
 | 
| 
MMOSimca@402
 | 
  1958         local log_source = event_name .. "- ExtrapolatedCurrentActionFromLootData"
 | 
| 
MMOSimca@402
 | 
  1959         local previous_spell_label = current_action.spell_label
 | 
| 
jcallahan@322
 | 
  1960         local extrapolated_guid_registry = {}
 | 
| 
jcallahan@322
 | 
  1961         local num_guids = 0
 | 
| 
MMOSimca@402
 | 
  1962         table.wipe(current_action)
 | 
| 
MMOSimca@402
 | 
  1963 
 | 
| 
MMOSimca@402
 | 
  1964         if _G.IsFishingLoot() then
 | 
| 
MMOSimca@402
 | 
  1965             -- Set up a proper 'fishing' current_action table
 | 
| 
MMOSimca@402
 | 
  1966             local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
 | 
| 
MMOSimca@402
 | 
  1967             if not (zone_name and area_id and x and y and map_level) then
 | 
| 
mmosimca@508
 | 
  1968                 if not (_G.IsInInstance()) then
 | 
| 
mmosimca@508
 | 
  1969                     Debug("%s: Missing current location data - %s, %s, %s, %s, %s.", log_source, tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
 | 
| 
mmosimca@508
 | 
  1970                 end
 | 
| 
MMOSimca@402
 | 
  1971                 return
 | 
| 
MMOSimca@402
 | 
  1972             end
 | 
| 
MMOSimca@402
 | 
  1973             current_action.instance_token = instance_token
 | 
| 
MMOSimca@402
 | 
  1974             current_action.map_level = map_level
 | 
| 
MMOSimca@402
 | 
  1975             current_action.x = x
 | 
| 
MMOSimca@402
 | 
  1976             current_action.y = y
 | 
| 
MMOSimca@402
 | 
  1977             current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
 | 
| 
MMOSimca@402
 | 
  1978             current_action.spell_label = "FISHING"
 | 
| 
MMOSimca@402
 | 
  1979             current_action.loot_label = "fishing"
 | 
| 
MMOSimca@402
 | 
  1980             current_action.identifier = "FISHING:NONE"
 | 
| 
MMOSimca@402
 | 
  1981             current_action.target_type = AF.ZONE
 | 
| 
MMOSimca@402
 | 
  1982 
 | 
| 
MMOSimca@402
 | 
  1983             Debug("%s: Fishing loot detected.", log_source)
 | 
| 
MMOSimca@402
 | 
  1984             return true
 | 
| 
MMOSimca@402
 | 
  1985         end
 | 
| 
jcallahan@322
 | 
  1986 
 | 
| 
MMOSimca@344
 | 
  1987         -- Loot extrapolation cannot handle objects that need special spell labels (like HERBALISM or MINING) (MIND_CONTROL is okay)
 | 
| 
MMOSimca@402
 | 
  1988         if previous_spell_label and private.SPELL_FLAGS_BY_LABEL[previous_spell_label] and not private.NON_LOOT_SPELL_LABELS[previous_spell_label] then
 | 
| 
MMOSimca@344
 | 
  1989             Debug("%s: Problematic spell label %s found. Loot extrapolation for this set of loot would have run an increased risk of introducing bad data into the system.", log_source, private.previous_spell_id)
 | 
| 
MMOSimca@344
 | 
  1990             return false
 | 
| 
MMOSimca@344
 | 
  1991         end
 | 
| 
MMOSimca@344
 | 
  1992 
 | 
| 
jcallahan@322
 | 
  1993         for loot_slot = 1, _G.GetNumLootItems() do
 | 
| 
jcallahan@322
 | 
  1994             local loot_info = {
 | 
| 
jcallahan@322
 | 
  1995                 _G.GetLootSourceInfo(loot_slot)
 | 
| 
jcallahan@322
 | 
  1996             }
 | 
| 
jcallahan@322
 | 
  1997 
 | 
| 
jcallahan@322
 | 
  1998             for loot_index = 1, #loot_info, 2 do
 | 
| 
jcallahan@322
 | 
  1999                 local source_guid = loot_info[loot_index]
 | 
| 
jcallahan@322
 | 
  2000 
 | 
| 
jcallahan@322
 | 
  2001                 if not extrapolated_guid_registry[source_guid] then
 | 
| 
jcallahan@322
 | 
  2002                     local unit_type, unit_idnum = ParseGUID(source_guid)
 | 
| 
jcallahan@322
 | 
  2003 
 | 
| 
jcallahan@322
 | 
  2004                     if unit_type and unit_idnum then
 | 
| 
jcallahan@322
 | 
  2005                         extrapolated_guid_registry[source_guid] = {
 | 
| 
jcallahan@322
 | 
  2006                             unit_type,
 | 
| 
jcallahan@322
 | 
  2007                             unit_idnum
 | 
| 
jcallahan@322
 | 
  2008                         }
 | 
| 
jcallahan@322
 | 
  2009 
 | 
| 
jcallahan@322
 | 
  2010                         num_guids = num_guids + 1
 | 
| 
jcallahan@322
 | 
  2011                     end
 | 
| 
jcallahan@322
 | 
  2012                 end
 | 
| 
jcallahan@322
 | 
  2013             end
 | 
| 
jcallahan@322
 | 
  2014         end
 | 
| 
jcallahan@322
 | 
  2015 
 | 
| 
jcallahan@322
 | 
  2016         if num_guids == 0 then
 | 
| 
jcallahan@322
 | 
  2017             Debug("%s: No GUIDs found in loot. Blank loot window?", log_source)
 | 
| 
jcallahan@322
 | 
  2018             return false
 | 
| 
jcallahan@322
 | 
  2019         end
 | 
| 
jcallahan@326
 | 
  2020 
 | 
| 
jcallahan@322
 | 
  2021         local num_npcs = 0
 | 
| 
jcallahan@322
 | 
  2022         local num_objects = 0
 | 
| 
jcallahan@324
 | 
  2023         local num_itemcontainers = 0
 | 
| 
jcallahan@322
 | 
  2024 
 | 
| 
jcallahan@322
 | 
  2025         for source_guid, guid_data in pairs(extrapolated_guid_registry) do
 | 
| 
jcallahan@322
 | 
  2026             local unit_type = guid_data[1]
 | 
| 
mmosimca@516
 | 
  2027             local loot_label = (unit_type == private.UNIT_TYPES.OBJECT) and "opening" or (UnitTypeIsNPC(unit_type) and "drops") or ((unit_type == private.UNIT_TYPES.ITEM) and "contains")
 | 
| 
jcallahan@322
 | 
  2028 
 | 
| 
jcallahan@322
 | 
  2029             if loot_label then
 | 
| 
jcallahan@322
 | 
  2030                 local unit_idnum = guid_data[2]
 | 
| 
jcallahan@322
 | 
  2031 
 | 
| 
jcallahan@322
 | 
  2032                 if loot_guid_registry[loot_label] and loot_guid_registry[loot_label][source_guid] then
 | 
| 
jcallahan@322
 | 
  2033                     Debug("%s: Previously scanned loot for unit with GUID %s and identifier %s.", log_source, source_guid, unit_idnum)
 | 
| 
jcallahan@322
 | 
  2034                 elseif unit_type == private.UNIT_TYPES.OBJECT and unit_idnum ~= OBJECT_ID_FISHING_BOBBER then
 | 
| 
jcallahan@322
 | 
  2035                     current_action.loot_label = loot_label
 | 
| 
jcallahan@322
 | 
  2036                     current_action.spell_label = "OPENING"
 | 
| 
jcallahan@322
 | 
  2037                     current_action.target_type = AF.OBJECT
 | 
| 
jcallahan@322
 | 
  2038                     current_action.identifier = unit_idnum
 | 
| 
jcallahan@322
 | 
  2039                     num_objects = num_objects + 1
 | 
| 
jcallahan@322
 | 
  2040                 elseif UnitTypeIsNPC(unit_type) then
 | 
| 
jcallahan@322
 | 
  2041                     current_action.loot_label = loot_label
 | 
| 
jcallahan@322
 | 
  2042                     current_action.target_type = AF.NPC
 | 
| 
jcallahan@322
 | 
  2043                     current_action.identifier = unit_idnum
 | 
| 
jcallahan@322
 | 
  2044                     num_npcs = num_npcs + 1
 | 
| 
mmosimca@516
 | 
  2045                 elseif unit_type == private.UNIT_TYPES.ITEM then
 | 
| 
jcallahan@324
 | 
  2046                     current_action.loot_label = loot_label
 | 
| 
jcallahan@324
 | 
  2047                     current_action.target_type = AF.ITEM
 | 
| 
jcallahan@324
 | 
  2048                     -- current_action.identifier assigned during loot verification.
 | 
| 
jcallahan@324
 | 
  2049                     num_itemcontainers = num_itemcontainers + 1
 | 
| 
jcallahan@322
 | 
  2050                 end
 | 
| 
jcallahan@322
 | 
  2051             else
 | 
| 
jcallahan@322
 | 
  2052                 -- Bail here; not only do we not know what this unit is, but we don't want to attribute loot to something that doesn't actually drop it.
 | 
| 
jcallahan@322
 | 
  2053                 Debug("%s: Unit with GUID %s has unsupported type for looting.", log_source, source_guid)
 | 
| 
jcallahan@322
 | 
  2054                 return false
 | 
| 
jcallahan@322
 | 
  2055             end
 | 
| 
jcallahan@322
 | 
  2056         end
 | 
| 
jcallahan@322
 | 
  2057 
 | 
| 
jcallahan@322
 | 
  2058         if not current_action.target_type then
 | 
| 
jcallahan@322
 | 
  2059             Debug("%s: Failure to obtain target_type.", log_source)
 | 
| 
jcallahan@322
 | 
  2060             return false
 | 
| 
jcallahan@322
 | 
  2061         end
 | 
| 
jcallahan@322
 | 
  2062 
 | 
| 
jcallahan@322
 | 
  2063         -- We can't figure out what dropped the loot. This shouldn't ever happen, but hey - Blizzard does some awesome stuff on occasion.
 | 
| 
jcallahan@324
 | 
  2064         if (num_npcs > 0 and num_objects + num_itemcontainers > 0) or (num_objects > 0 and num_npcs + num_itemcontainers > 0) or (num_itemcontainers > 0 and num_npcs + num_objects > 0) then
 | 
| 
jcallahan@324
 | 
  2065             Debug("%s: Mixed target types are not supported. NPCs - %d, Objects - %d, Item Containers - %d.", log_source, num_npcs, num_objects, num_itemcontainers)
 | 
| 
jcallahan@322
 | 
  2066             return false
 | 
| 
jcallahan@322
 | 
  2067         end
 | 
| 
jcallahan@322
 | 
  2068 
 | 
| 
jcallahan@322
 | 
  2069         return true
 | 
| 
jcallahan@322
 | 
  2070     end
 | 
| 
jcallahan@322
 | 
  2071 
 | 
| 
jcallahan@322
 | 
  2072 
 | 
| 
MMOSimca@343
 | 
  2073     function WDP:LOOT_OPENED(event_name)
 | 
| 
MMOSimca@398
 | 
  2074         ClearChatLootData()
 | 
| 
MMOSimca@387
 | 
  2075 
 | 
| 
jcallahan@132
 | 
  2076         if current_loot then
 | 
| 
jcallahan@322
 | 
  2077             current_loot = nil
 | 
| 
jcallahan@322
 | 
  2078             Debug("%s: Previous loot did not process in time for this event. Attempting to extrapolate current_action from loot data.", event_name)
 | 
| 
jcallahan@322
 | 
  2079 
 | 
| 
jcallahan@322
 | 
  2080             if not ExtrapolatedCurrentActionFromLootData(event_name) then
 | 
| 
jcallahan@322
 | 
  2081                 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
 | 
| 
jcallahan@322
 | 
  2082                 return
 | 
| 
jcallahan@322
 | 
  2083             end
 | 
| 
jcallahan@18
 | 
  2084         end
 | 
| 
jcallahan@151
 | 
  2085 
 | 
| 
jcallahan@151
 | 
  2086         if not current_action.target_type then
 | 
| 
jcallahan@322
 | 
  2087             if not ExtrapolatedCurrentActionFromLootData(event_name) then
 | 
| 
jcallahan@322
 | 
  2088                 Debug("%s: Unable to extrapolate current_action. Aborting attempts to handle loot for now.", event_name)
 | 
| 
jcallahan@322
 | 
  2089                 return
 | 
| 
jcallahan@322
 | 
  2090             end
 | 
| 
jcallahan@151
 | 
  2091         end
 | 
| 
MMOSimca@343
 | 
  2092         local verify_func = LOOT_OPENED_VERIFY_FUNCS[current_action.target_type]
 | 
| 
MMOSimca@343
 | 
  2093         local update_func = LOOT_OPENED_UPDATE_FUNCS[current_action.target_type]
 | 
| 
jcallahan@13
 | 
  2094 
 | 
| 
jcallahan@14
 | 
  2095         if not verify_func or not update_func then
 | 
| 
jcallahan@322
 | 
  2096             Debug("%s: The current action's target type is unsupported or nil.", event_name)
 | 
| 
jcallahan@13
 | 
  2097             return
 | 
| 
jcallahan@13
 | 
  2098         end
 | 
| 
jcallahan@13
 | 
  2099 
 | 
| 
mmosimca@522
 | 
  2100         if type(verify_func) == "function" and not verify_func() then
 | 
| 
jcallahan@324
 | 
  2101             Debug("%s: The current action type, %s, is supported but has failed loot verification.", event_name, private.ACTION_TYPE_NAMES[current_action.target_type])
 | 
| 
jcallahan@14
 | 
  2102             return
 | 
| 
jcallahan@14
 | 
  2103         end
 | 
| 
jcallahan@80
 | 
  2104         local guids_used = {}
 | 
| 
jcallahan@132
 | 
  2105 
 | 
| 
jcallahan@301
 | 
  2106         InitializeCurrentLoot()
 | 
| 
jcallahan@217
 | 
  2107         loot_guid_registry[current_loot.label] = loot_guid_registry[current_loot.label] or {}
 | 
| 
jcallahan@217
 | 
  2108 
 | 
| 
jcallahan@55
 | 
  2109         for loot_slot = 1, _G.GetNumLootItems() do
 | 
| 
MMOSimca@581
 | 
  2110             local texture_filedata_id, item_text, slot_quantity, _, locked = _G.GetLootSlotInfo(loot_slot)
 | 
| 
jcallahan@55
 | 
  2111             local slot_type = _G.GetLootSlotType(loot_slot)
 | 
| 
catherton@463
 | 
  2112             local loot_info = { _G.GetLootSourceInfo(loot_slot) }
 | 
| 
catherton@464
 | 
  2113             local loot_link = _G.GetLootSlotLink(loot_slot)
 | 
| 
jcallahan@13
 | 
  2114 
 | 
| 
jcallahan@237
 | 
  2115             -- Odd index is GUID, even is count.
 | 
| 
jcallahan@237
 | 
  2116             for loot_index = 1, #loot_info, 2 do
 | 
| 
jcallahan@237
 | 
  2117                 local source_guid = loot_info[loot_index]
 | 
| 
jcallahan@75
 | 
  2118 
 | 
| 
jcallahan@237
 | 
  2119                 if not loot_guid_registry[current_loot.label][source_guid] then
 | 
| 
jcallahan@237
 | 
  2120                     local loot_quantity = loot_info[loot_index + 1]
 | 
| 
jcallahan@324
 | 
  2121                     -- There is a new bug in 5.4.0 that causes GetLootSlotInfo() to (rarely) return nil values for slot_quantity.
 | 
| 
jcallahan@324
 | 
  2122                     if slot_quantity then
 | 
| 
jcallahan@324
 | 
  2123                         -- We need slot_quantity to account for an old bug where loot_quantity is sometimes '1' for stacks of items, such as cloth.
 | 
| 
jcallahan@324
 | 
  2124                         if slot_quantity > loot_quantity then
 | 
| 
jcallahan@324
 | 
  2125                             loot_quantity = slot_quantity
 | 
| 
jcallahan@324
 | 
  2126                         end
 | 
| 
jcallahan@324
 | 
  2127                         local source_type, source_id = ParseGUID(source_guid)
 | 
| 
MMOSimca@329
 | 
  2128                         local source_key = ("%s:%d"):format(source_type, source_id)
 | 
| 
jcallahan@324
 | 
  2129 
 | 
| 
MMOSimca@581
 | 
  2130                         if slot_type == ENUM_LOOTSLOTTYPE_ITEM then
 | 
| 
catherton@464
 | 
  2131                             if loot_link then
 | 
| 
catherton@464
 | 
  2132                                 local item_id = ItemLinkToID(loot_link)
 | 
| 
catherton@464
 | 
  2133                                 Debug("GUID: %s - Type:ID: %s - ItemID: %d - Amount: %d (%d)", loot_info[loot_index], source_key, item_id, loot_info[loot_index + 1], slot_quantity)
 | 
| 
catherton@464
 | 
  2134                                 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
 | 
| 
catherton@464
 | 
  2135                                 current_loot.sources[source_guid][item_id] = (current_loot.sources[source_guid][item_id] or 0) + loot_quantity
 | 
| 
catherton@464
 | 
  2136                                 guids_used[source_guid] = true
 | 
| 
catherton@463
 | 
  2137                             else
 | 
| 
catherton@463
 | 
  2138                                 Debug("%s: Loot link is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
 | 
| 
catherton@463
 | 
  2139                             end
 | 
| 
MMOSimca@581
 | 
  2140                         elseif slot_type == ENUM_LOOTSLOTTYPE_MONEY then
 | 
| 
jcallahan@324
 | 
  2141                             Debug("GUID: %s - Type:ID: %s - Money - Amount: %d (%d)", loot_info[loot_index], source_key, loot_info[loot_index + 1], slot_quantity)
 | 
| 
jcallahan@324
 | 
  2142                             if current_loot.target_type == AF.ZONE then
 | 
| 
jcallahan@324
 | 
  2143                                 table.insert(current_loot.list, ("money:%d"):format(loot_quantity))
 | 
| 
jcallahan@324
 | 
  2144                             else
 | 
| 
jcallahan@324
 | 
  2145                                 current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
 | 
| 
MMOSimca@367
 | 
  2146                                 current_loot.sources[source_guid]["money"] = (current_loot.sources[source_guid]["money"] or 0) + loot_quantity
 | 
| 
jcallahan@324
 | 
  2147                                 guids_used[source_guid] = true
 | 
| 
jcallahan@324
 | 
  2148                             end
 | 
| 
MMOSimca@581
 | 
  2149                         elseif slot_type == ENUM_LOOTSLOTTYPE_CURRENCY then
 | 
| 
jcallahan@324
 | 
  2150                             -- Same bug with GetLootSlotInfo() will screw up currency when it happens, so we won't process this slot's loot.
 | 
| 
catherton@463
 | 
  2151                             if loot_link then
 | 
| 
mmosimca@496
 | 
  2152                                 local currency_id = CurrencyLinkToID(loot_link)
 | 
| 
mmosimca@496
 | 
  2153                                 Debug("GUID: %s - Type:ID: %s - Currency: %d - Amount: %d (%d)", loot_info[loot_index], source_key, currency_id, loot_info[loot_index + 1], slot_quantity)
 | 
| 
jcallahan@324
 | 
  2154                                 if current_loot.target_type == AF.ZONE then
 | 
| 
mmosimca@496
 | 
  2155                                     table.insert(current_loot.list, ("currency:%d:%d"):format(loot_quantity, currency_id))
 | 
| 
jcallahan@324
 | 
  2156                                 else
 | 
| 
mmosimca@496
 | 
  2157                                     local currency_token = ("currency:%d"):format(currency_id)
 | 
| 
jcallahan@324
 | 
  2158 
 | 
| 
jcallahan@324
 | 
  2159                                     current_loot.sources[source_guid] = current_loot.sources[source_guid] or {}
 | 
| 
MMOSimca@367
 | 
  2160                                     current_loot.sources[source_guid][currency_token] = (current_loot.sources[source_guid][currency_token] or 0) + loot_quantity
 | 
| 
jcallahan@324
 | 
  2161                                     guids_used[source_guid] = true
 | 
| 
jcallahan@324
 | 
  2162                                 end
 | 
| 
jcallahan@324
 | 
  2163                             else
 | 
| 
catherton@463
 | 
  2164                                 Debug("%s: Loot link is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
 | 
| 
jcallahan@324
 | 
  2165                             end
 | 
| 
MMOSimca@581
 | 
  2166 						else
 | 
| 
MMOSimca@581
 | 
  2167                             Debug("Unknown LootSlotType %d. GUID: %s - Type:ID: %s - Loot Slot: %d - Loot Link: %s", slot_type, loot_info[loot_index], source_key, loot_slot, loot_link or "")
 | 
| 
jcallahan@308
 | 
  2168                         end
 | 
| 
jcallahan@324
 | 
  2169                     else
 | 
| 
jcallahan@324
 | 
  2170                         -- If this is nil, then the item's quantity could be wrong if loot_quantity is wrong, so we won't process this slot's loot.
 | 
| 
catherton@463
 | 
  2171                         Debug("%s: Slot quantity is nil for loot slot %d of the entity with GUID %s and Type:ID: %s.", event_name, loot_slot, loot_info[loot_index], source_key)
 | 
| 
jcallahan@79
 | 
  2172                     end
 | 
| 
jcallahan@75
 | 
  2173                 end
 | 
| 
jcallahan@13
 | 
  2174             end
 | 
| 
jcallahan@13
 | 
  2175         end
 | 
| 
jcallahan@80
 | 
  2176 
 | 
| 
jcallahan@81
 | 
  2177         for guid in pairs(guids_used) do
 | 
| 
jcallahan@217
 | 
  2178             loot_guid_registry[current_loot.label][guid] = true
 | 
| 
jcallahan@80
 | 
  2179         end
 | 
| 
jcallahan@13
 | 
  2180         update_func()
 | 
| 
jcallahan@1
 | 
  2181     end
 | 
| 
jcallahan@13
 | 
  2182 end -- do-block
 | 
| 
jcallahan@0
 | 
  2183 
 | 
| 
jcallahan@0
 | 
  2184 
 | 
| 
jcallahan@89
 | 
  2185 function WDP:MAIL_SHOW(event_name)
 | 
| 
MMOSimca@436
 | 
  2186     WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@89
 | 
  2187     local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@89
 | 
  2188 
 | 
| 
jcallahan@89
 | 
  2189     if not unit_idnum or unit_type ~= private.UNIT_TYPES.OBJECT then
 | 
| 
jcallahan@89
 | 
  2190         return
 | 
| 
jcallahan@89
 | 
  2191     end
 | 
| 
jcallahan@89
 | 
  2192     UpdateDBEntryLocation("objects", unit_idnum)
 | 
| 
jcallahan@89
 | 
  2193 end
 | 
| 
jcallahan@89
 | 
  2194 
 | 
| 
jcallahan@89
 | 
  2195 
 | 
| 
jcallahan@44
 | 
  2196 do
 | 
| 
jcallahan@44
 | 
  2197     local POINT_MATCH_PATTERNS = {
 | 
| 
jcallahan@44
 | 
  2198         ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING:gsub("%%d", "(%%d+)")), -- May no longer be necessary
 | 
| 
jcallahan@44
 | 
  2199         ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3:gsub("%%d", "(%%d+)")), -- May no longer be necessary
 | 
| 
jcallahan@44
 | 
  2200         ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_5V5:gsub("%%d", "(%%d+)")), -- May no longer be necessary
 | 
| 
jcallahan@44
 | 
  2201         ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_BG:gsub("%%d", "(%%d+)")),
 | 
| 
jcallahan@44
 | 
  2202         ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3_BG:gsub("%%d", "(%%d+)")),
 | 
| 
jcallahan@44
 | 
  2203     }
 | 
| 
jcallahan@5
 | 
  2204 
 | 
| 
jcallahan@68
 | 
  2205     local ITEM_REQ_REPUTATION_MATCH = "Requires (.-) %- (.*)"
 | 
| 
jcallahan@87
 | 
  2206     local ITEM_REQ_QUEST_MATCH1 = "Requires: .*"
 | 
| 
jcallahan@87
 | 
  2207     local ITEM_REQ_QUEST_MATCH2 = "Must have completed: .*"
 | 
| 
jcallahan@68
 | 
  2208 
 | 
| 
jcallahan@133
 | 
  2209     local current_merchant
 | 
| 
jcallahan@133
 | 
  2210     local merchant_standing
 | 
| 
jcallahan@133
 | 
  2211 
 | 
| 
jcallahan@133
 | 
  2212     function WDP:MERCHANT_CLOSED(event_name)
 | 
| 
MMOSimca@436
 | 
  2213         WDP:ResumeChatLootRecording(event_name)
 | 
| 
jcallahan@133
 | 
  2214         current_merchant = nil
 | 
| 
jcallahan@133
 | 
  2215         merchant_standing = nil
 | 
| 
jcallahan@133
 | 
  2216     end
 | 
| 
jcallahan@133
 | 
  2217 
 | 
| 
jcallahan@133
 | 
  2218 
 | 
| 
jcallahan@89
 | 
  2219     function WDP:UpdateMerchantItems(event_name)
 | 
| 
jcallahan@144
 | 
  2220         if not current_merchant or event_name == "MERCHANT_SHOW" then
 | 
| 
MMOSimca@436
 | 
  2221             WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@195
 | 
  2222             local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@4
 | 
  2223 
 | 
| 
jcallahan@171
 | 
  2224             if not unit_idnum or not UnitTypeIsNPC(unit_type) then
 | 
| 
jcallahan@133
 | 
  2225                 return
 | 
| 
jcallahan@133
 | 
  2226             end
 | 
| 
MMOSimca@584
 | 
  2227             
 | 
| 
MMOSimca@584
 | 
  2228             -- Can't do this in instances now, at least not by tooltip unit scanning
 | 
| 
MMOSimca@585
 | 
  2229             if false then
 | 
| 
MMOSimca@584
 | 
  2230                 local _, faction_standing = UnitFactionStanding("npc")
 | 
| 
MMOSimca@584
 | 
  2231                 merchant_standing = faction_standing
 | 
| 
MMOSimca@584
 | 
  2232             end
 | 
| 
MMOSimca@584
 | 
  2233             
 | 
| 
jcallahan@133
 | 
  2234             current_merchant = NPCEntry(unit_idnum)
 | 
| 
jcallahan@133
 | 
  2235             current_merchant.sells = current_merchant.sells or {}
 | 
| 
jcallahan@44
 | 
  2236         end
 | 
| 
jcallahan@55
 | 
  2237         local current_filters = _G.GetMerchantFilter()
 | 
| 
jcallahan@57
 | 
  2238         _G.SetMerchantFilter(_G.LE_LOOT_FILTER_ALL)
 | 
| 
jcallahan@57
 | 
  2239         _G.MerchantFrame_Update()
 | 
| 
jcallahan@57
 | 
  2240 
 | 
| 
jcallahan@150
 | 
  2241         local num_items = _G.GetMerchantNumItems()
 | 
| 
jcallahan@150
 | 
  2242 
 | 
| 
jcallahan@44
 | 
  2243         for item_index = 1, num_items do
 | 
| 
MMOSimca@584
 | 
  2244             local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.C_MerchantFrame.GetItemInfo(item_index)
 | 
| 
MMOSimca@584
 | 
  2245             local itemInfoTable = _G.C_MerchantFrame.GetItemInfo(item_index)
 | 
| 
jcallahan@44
 | 
  2246             local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index))
 | 
| 
jcallahan@5
 | 
  2247 
 | 
| 
jcallahan@324
 | 
  2248             DatamineTT:ClearLines()
 | 
| 
jcallahan@324
 | 
  2249             DatamineTT:SetMerchantItem(item_index)
 | 
| 
jcallahan@324
 | 
  2250 
 | 
| 
jcallahan@324
 | 
  2251             if not item_id then
 | 
| 
jcallahan@324
 | 
  2252                 local item_name, item_link = DatamineTT:GetItem()
 | 
| 
jcallahan@324
 | 
  2253                 item_id = ItemLinkToID(item_link)
 | 
| 
MMOSimca@354
 | 
  2254                 -- GetMerchantItemLink() still ocassionally fails as of Patch 6.0.2. It fails so badly that debug functions cause considerable slowdown.
 | 
| 
jcallahan@324
 | 
  2255             end
 | 
| 
jcallahan@324
 | 
  2256 
 | 
| 
jcallahan@44
 | 
  2257             if item_id and item_id > 0 then
 | 
| 
MMOSimca@584
 | 
  2258                 local price_string = ActualCopperCost(itemInfoTable.price, merchant_standing)
 | 
| 
jcallahan@5
 | 
  2259 
 | 
| 
jcallahan@68
 | 
  2260                 local num_lines = DatamineTT:NumLines()
 | 
| 
jcallahan@68
 | 
  2261 
 | 
| 
jcallahan@68
 | 
  2262                 for line_index = 1, num_lines do
 | 
| 
jcallahan@68
 | 
  2263                     local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
 | 
| 
jcallahan@68
 | 
  2264 
 | 
| 
jcallahan@68
 | 
  2265                     if not current_line then
 | 
| 
jcallahan@68
 | 
  2266                         break
 | 
| 
jcallahan@68
 | 
  2267                     end
 | 
| 
jcallahan@68
 | 
  2268                     local faction, reputation = current_line:GetText():match(ITEM_REQ_REPUTATION_MATCH)
 | 
| 
jcallahan@68
 | 
  2269 
 | 
| 
jcallahan@68
 | 
  2270                     if faction or reputation then
 | 
| 
jcallahan@68
 | 
  2271                         DBEntry("items", item_id).req_reputation = ("%s:%s"):format(faction:gsub("-", ""), reputation:upper())
 | 
| 
jcallahan@68
 | 
  2272                         break
 | 
| 
jcallahan@68
 | 
  2273                     end
 | 
| 
jcallahan@68
 | 
  2274                 end
 | 
| 
jcallahan@68
 | 
  2275 
 | 
| 
jcallahan@87
 | 
  2276                 for line_index = 1, num_lines do
 | 
| 
jcallahan@87
 | 
  2277                     local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
 | 
| 
jcallahan@87
 | 
  2278 
 | 
| 
jcallahan@87
 | 
  2279                     if not current_line then
 | 
| 
jcallahan@87
 | 
  2280                         break
 | 
| 
jcallahan@87
 | 
  2281                     end
 | 
| 
jcallahan@87
 | 
  2282                     local line_text = current_line:GetText()
 | 
| 
jcallahan@87
 | 
  2283                     local quest_name = line_text:match(ITEM_REQ_QUEST_MATCH1) or line_text:match(ITEM_REQ_QUEST_MATCH2)
 | 
| 
jcallahan@87
 | 
  2284 
 | 
| 
jcallahan@87
 | 
  2285                     if quest_name then
 | 
| 
jcallahan@87
 | 
  2286                         DBEntry("items", item_id).req_quest = ("%s"):format(quest_name:gsub("(.+): ", ""), quest_name)
 | 
| 
jcallahan@87
 | 
  2287                         break
 | 
| 
jcallahan@87
 | 
  2288                     end
 | 
| 
jcallahan@87
 | 
  2289                 end
 | 
| 
jcallahan@87
 | 
  2290 
 | 
| 
MMOSimca@584
 | 
  2291                 if itemInfoTable.hasExtendedCost then
 | 
| 
jcallahan@53
 | 
  2292                     local battleground_rating = 0
 | 
| 
jcallahan@53
 | 
  2293                     local personal_rating = 0
 | 
| 
jcallahan@53
 | 
  2294                     local required_season_amount
 | 
| 
jcallahan@5
 | 
  2295 
 | 
| 
jcallahan@68
 | 
  2296                     for line_index = 1, num_lines do
 | 
| 
jcallahan@44
 | 
  2297                         local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
 | 
| 
jcallahan@5
 | 
  2298 
 | 
| 
jcallahan@44
 | 
  2299                         if not current_line then
 | 
| 
jcallahan@44
 | 
  2300                             break
 | 
| 
jcallahan@44
 | 
  2301                         end
 | 
| 
jcallahan@53
 | 
  2302                         required_season_amount = current_line:GetText():match("Requires earning a total of (%d+)\n(.-) for the season.")
 | 
| 
jcallahan@5
 | 
  2303 
 | 
| 
jcallahan@44
 | 
  2304                         for match_index = 1, #POINT_MATCH_PATTERNS do
 | 
| 
jcallahan@44
 | 
  2305                             local match1, match2 = current_line:GetText():match(POINT_MATCH_PATTERNS[match_index])
 | 
| 
jcallahan@53
 | 
  2306                             personal_rating = personal_rating + (match1 or 0)
 | 
| 
jcallahan@53
 | 
  2307                             battleground_rating = battleground_rating + (match2 or 0)
 | 
| 
jcallahan@5
 | 
  2308 
 | 
| 
jcallahan@44
 | 
  2309                             if match1 or match2 then
 | 
| 
jcallahan@44
 | 
  2310                                 break
 | 
| 
jcallahan@44
 | 
  2311                             end
 | 
| 
jcallahan@44
 | 
  2312                         end
 | 
| 
jcallahan@5
 | 
  2313                     end
 | 
| 
jcallahan@44
 | 
  2314                     local currency_list = {}
 | 
| 
jcallahan@44
 | 
  2315                     local item_count = _G.GetMerchantItemCostInfo(item_index)
 | 
| 
jcallahan@50
 | 
  2316 
 | 
| 
mmosimca@518
 | 
  2317                     -- Keeping this around in case Blizzard makes the two ratings (personal and battleground) diverge at some point
 | 
| 
mmosimca@518
 | 
  2318                     --price_string = ("%s:%s:%s:%s"):format(price_string, battleground_rating, personal_rating, required_season_amount or 0)
 | 
| 
jcallahan@53
 | 
  2319                     price_string = ("%s:%s:%s"):format(price_string, personal_rating, required_season_amount or 0)
 | 
| 
jcallahan@5
 | 
  2320 
 | 
| 
jcallahan@44
 | 
  2321                     for cost_index = 1, item_count do
 | 
| 
jcallahan@324
 | 
  2322                         -- The third return (Blizz calls "currency_link") of GetMerchantItemCostItem only returns item links as of Patch 5.3.0.
 | 
| 
MMOSimca@540
 | 
  2323                         local texture_id, amount_required, hyperlink, name = _G.GetMerchantItemCostItem(item_index, cost_index)
 | 
| 
mmosimca@496
 | 
  2324 
 | 
| 
MMOSimca@581
 | 
  2325 						if hyperlink then 
 | 
| 
MMOSimca@581
 | 
  2326 							-- Try to get item ID
 | 
| 
MMOSimca@581
 | 
  2327 							local item_id = ItemLinkToID(hyperlink)
 | 
| 
MMOSimca@581
 | 
  2328 
 | 
| 
MMOSimca@581
 | 
  2329 							-- FUTURE: At some point, we should make the output from these two cases (item_id vs currency_id) slightly different, so that WoWDB doesn't have to guess if it is a currency or item
 | 
| 
MMOSimca@581
 | 
  2330 							-- Handle cases when the additional cost is another item
 | 
| 
MMOSimca@581
 | 
  2331 							if item_id and item_id > 0 then
 | 
| 
MMOSimca@581
 | 
  2332 								currency_list[#currency_list + 1] = ("(%s:%d)"):format(amount_required, item_id)
 | 
| 
MMOSimca@581
 | 
  2333 							else
 | 
| 
MMOSimca@581
 | 
  2334 								-- Try to get currency ID
 | 
| 
MMOSimca@581
 | 
  2335 								local currency_id = CurrencyLinkToID(hyperlink)
 | 
| 
MMOSimca@581
 | 
  2336 								if currency_id and currency_id > 0 then
 | 
| 
MMOSimca@581
 | 
  2337 									currency_list[#currency_list + 1] = ("(%s:%d)"):format(amount_required, currency_id)
 | 
| 
MMOSimca@581
 | 
  2338 								else
 | 
| 
MMOSimca@581
 | 
  2339 									Debug("UpdateMerchantItems: Failed to get item ID and failed to get currency ID for item index %d and cost index %d with hyperlink %s", item_index, cost_index, hyperlink)
 | 
| 
MMOSimca@581
 | 
  2340 								end
 | 
| 
MMOSimca@581
 | 
  2341 							end
 | 
| 
MMOSimca@581
 | 
  2342 						end
 | 
| 
jcallahan@44
 | 
  2343                     end
 | 
| 
jcallahan@44
 | 
  2344 
 | 
| 
jcallahan@44
 | 
  2345                     for currency_index = 1, #currency_list do
 | 
| 
jcallahan@44
 | 
  2346                         price_string = ("%s:%s"):format(price_string, currency_list[currency_index])
 | 
| 
jcallahan@5
 | 
  2347                     end
 | 
| 
jcallahan@5
 | 
  2348                 end
 | 
| 
MMOSimca@584
 | 
  2349                 current_merchant.sells[item_id] = ("%s:%s:[%s]"):format(itemInfoTable.numAvailable, itemInfoTable.stackCount, price_string)
 | 
| 
jcallahan@44
 | 
  2350             end
 | 
| 
jcallahan@44
 | 
  2351         end
 | 
| 
jcallahan@5
 | 
  2352 
 | 
| 
jcallahan@44
 | 
  2353         if _G.CanMerchantRepair() then
 | 
| 
jcallahan@133
 | 
  2354             current_merchant.can_repair = true
 | 
| 
jcallahan@5
 | 
  2355         end
 | 
| 
jcallahan@57
 | 
  2356         _G.SetMerchantFilter(current_filters)
 | 
| 
jcallahan@57
 | 
  2357         _G.MerchantFrame_Update()
 | 
| 
jcallahan@4
 | 
  2358     end
 | 
| 
jcallahan@44
 | 
  2359 end -- do-block
 | 
| 
jcallahan@4
 | 
  2360 
 | 
| 
jcallahan@89
 | 
  2361 
 | 
| 
jcallahan@92
 | 
  2362 function WDP:PET_BAR_UPDATE(event_name)
 | 
| 
MMOSimca@336
 | 
  2363     if not private.NON_LOOT_SPELL_LABELS[current_action.spell_label] then
 | 
| 
jcallahan@25
 | 
  2364         return
 | 
| 
jcallahan@25
 | 
  2365     end
 | 
| 
jcallahan@34
 | 
  2366     local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("pet"))
 | 
| 
jcallahan@25
 | 
  2367 
 | 
| 
jcallahan@171
 | 
  2368     if not unit_idnum or not UnitTypeIsNPC(unit_type) then
 | 
| 
jcallahan@25
 | 
  2369         return
 | 
| 
jcallahan@25
 | 
  2370     end
 | 
| 
jcallahan@29
 | 
  2371     NPCEntry(unit_idnum).mind_control = true
 | 
| 
jcallahan@122
 | 
  2372     table.wipe(current_action)
 | 
| 
jcallahan@25
 | 
  2373 end
 | 
| 
jcallahan@25
 | 
  2374 
 | 
| 
jcallahan@25
 | 
  2375 
 | 
| 
MMOSimca@368
 | 
  2376 -- This function produces data currently unused by wowdb.com, and it causes unneeded bloat in the raw lua DB.
 | 
| 
MMOSimca@442
 | 
  2377 --[[local LPJ = LibStub("LibPetJournal-2.0")
 | 
| 
MMOSimca@442
 | 
  2378 function WDP:PET_JOURNAL_LIST_UPDATE(event_name)
 | 
| 
MMOSimca@346
 | 
  2379     if DEBUGGING then
 | 
| 
jcallahan@309
 | 
  2380         return
 | 
| 
jcallahan@309
 | 
  2381     end
 | 
| 
jcallahan@309
 | 
  2382 
 | 
| 
jcallahan@115
 | 
  2383     local num_pets = LPJ:NumPets()
 | 
| 
jcallahan@115
 | 
  2384 
 | 
| 
jcallahan@115
 | 
  2385     for index, pet_id in LPJ:IteratePetIDs() do
 | 
| 
jcallahan@115
 | 
  2386         local _, _, is_owned, _, level, _, _, name, icon, pet_type, npc_id, _, _, is_wild = _G.C_PetJournal.GetPetInfoByIndex(index)
 | 
| 
jcallahan@115
 | 
  2387 
 | 
| 
jcallahan@115
 | 
  2388         if is_owned then
 | 
| 
jcallahan@115
 | 
  2389             local health, max_health, attack, speed, rarity = _G.C_PetJournal.GetPetStats(pet_id)
 | 
| 
jcallahan@115
 | 
  2390 
 | 
| 
jcallahan@139
 | 
  2391             if rarity then
 | 
| 
jcallahan@139
 | 
  2392                 local rarity_name = _G["BATTLE_PET_BREED_QUALITY" .. rarity]
 | 
| 
jcallahan@139
 | 
  2393                 local npc = NPCEntry(npc_id)
 | 
| 
jcallahan@139
 | 
  2394                 npc.wild_pet = is_wild or nil
 | 
| 
jcallahan@139
 | 
  2395                 npc.battle_pet_data = npc.battle_pet_data or {}
 | 
| 
jcallahan@139
 | 
  2396                 npc.battle_pet_data[rarity_name] = npc.battle_pet_data[rarity_name] or {}
 | 
| 
jcallahan@139
 | 
  2397                 npc.battle_pet_data[rarity_name]["level_" .. level] = npc.battle_pet_data[rarity_name]["level_" .. level] or {}
 | 
| 
jcallahan@139
 | 
  2398 
 | 
| 
jcallahan@139
 | 
  2399                 local data = npc.battle_pet_data[rarity_name]["level_" .. level]
 | 
| 
jcallahan@139
 | 
  2400                 data.max_health = max_health
 | 
| 
jcallahan@139
 | 
  2401                 data.attack = attack
 | 
| 
jcallahan@139
 | 
  2402                 data.speed = speed
 | 
| 
jcallahan@139
 | 
  2403             end
 | 
| 
jcallahan@115
 | 
  2404         end
 | 
| 
jcallahan@115
 | 
  2405     end
 | 
| 
MMOSimca@368
 | 
  2406 end]]--
 | 
| 
jcallahan@115
 | 
  2407 
 | 
| 
jcallahan@115
 | 
  2408 
 | 
| 
jcallahan@156
 | 
  2409 function WDP:PLAYER_REGEN_DISABLED(event_name)
 | 
| 
jcallahan@156
 | 
  2410     private.in_combat = true
 | 
| 
jcallahan@156
 | 
  2411 end
 | 
| 
jcallahan@156
 | 
  2412 
 | 
| 
jcallahan@156
 | 
  2413 
 | 
| 
jcallahan@156
 | 
  2414 function WDP:PLAYER_REGEN_ENABLED(event_name)
 | 
| 
jcallahan@156
 | 
  2415     private.in_combat = nil
 | 
| 
jcallahan@156
 | 
  2416 end
 | 
| 
jcallahan@156
 | 
  2417 
 | 
| 
jcallahan@156
 | 
  2418 
 | 
| 
jcallahan@118
 | 
  2419 function WDP:PLAYER_TARGET_CHANGED(event_name)
 | 
| 
jcallahan@215
 | 
  2420     if not TargetedNPC() then
 | 
| 
jcallahan@118
 | 
  2421         return
 | 
| 
jcallahan@2
 | 
  2422     end
 | 
| 
jcallahan@151
 | 
  2423     current_action.target_type = AF.NPC
 | 
| 
jcallahan@118
 | 
  2424     self:UpdateTargetLocation()
 | 
| 
jcallahan@118
 | 
  2425 end
 | 
| 
jcallahan@2
 | 
  2426 
 | 
| 
jcallahan@89
 | 
  2427 
 | 
| 
jcallahan@12
 | 
  2428 do
 | 
| 
jcallahan@12
 | 
  2429     local function UpdateQuestJuncture(point)
 | 
| 
jcallahan@12
 | 
  2430         local unit_name = _G.UnitName("questnpc")
 | 
| 
jcallahan@9
 | 
  2431 
 | 
| 
jcallahan@12
 | 
  2432         if not unit_name then
 | 
| 
jcallahan@12
 | 
  2433             return
 | 
| 
jcallahan@12
 | 
  2434         end
 | 
| 
jcallahan@34
 | 
  2435         local unit_type, unit_id = ParseGUID(_G.UnitGUID("questnpc"))
 | 
| 
MMOSimca@351
 | 
  2436         Debug("UpdateQuestJuncture: Updating quest juncture for %s.", ("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id))
 | 
| 
jcallahan@12
 | 
  2437         if unit_type == private.UNIT_TYPES.OBJECT then
 | 
| 
jcallahan@38
 | 
  2438             UpdateDBEntryLocation("objects", unit_id)
 | 
| 
jcallahan@12
 | 
  2439         end
 | 
| 
jcallahan@19
 | 
  2440         local quest = DBEntry("quests", _G.GetQuestID())
 | 
| 
jcallahan@12
 | 
  2441         quest[point] = quest[point] or {}
 | 
| 
MMOSimca@329
 | 
  2442         quest[point][("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type], unit_id)] = true
 | 
| 
jcallahan@24
 | 
  2443 
 | 
| 
jcallahan@24
 | 
  2444         return quest
 | 
| 
jcallahan@12
 | 
  2445     end
 | 
| 
jcallahan@10
 | 
  2446 
 | 
| 
jcallahan@12
 | 
  2447 
 | 
| 
jcallahan@92
 | 
  2448     function WDP:QUEST_COMPLETE(event_name)
 | 
| 
jcallahan@97
 | 
  2449         local quest = UpdateQuestJuncture("end")
 | 
| 
catherton@465
 | 
  2450 
 | 
| 
MMOSimca@446
 | 
  2451         if not quest then
 | 
| 
MMOSimca@446
 | 
  2452             return
 | 
| 
MMOSimca@446
 | 
  2453         end
 | 
| 
jcallahan@97
 | 
  2454 
 | 
| 
jcallahan@112
 | 
  2455         if ALLOWED_LOCALES[CLIENT_LOCALE] then
 | 
| 
jcallahan@112
 | 
  2456             quest.reward_text = ReplaceKeywords(_G.GetRewardText())
 | 
| 
jcallahan@112
 | 
  2457         end
 | 
| 
jcallahan@67
 | 
  2458         -- Make sure the quest NPC isn't erroneously recorded as giving reputation for quests which award it.
 | 
| 
jcallahan@177
 | 
  2459         ClearKilledNPC()
 | 
| 
jcallahan@10
 | 
  2460     end
 | 
| 
jcallahan@10
 | 
  2461 
 | 
| 
jcallahan@12
 | 
  2462 
 | 
| 
jcallahan@92
 | 
  2463     function WDP:QUEST_DETAIL(event_name)
 | 
| 
jcallahan@24
 | 
  2464         local quest = UpdateQuestJuncture("begin")
 | 
| 
jcallahan@24
 | 
  2465 
 | 
| 
jcallahan@46
 | 
  2466         if not quest then
 | 
| 
jcallahan@46
 | 
  2467             return
 | 
| 
jcallahan@46
 | 
  2468         end
 | 
| 
jcallahan@24
 | 
  2469         quest.classes = quest.classes or {}
 | 
| 
jcallahan@27
 | 
  2470         quest.classes[PLAYER_CLASS] = true
 | 
| 
jcallahan@24
 | 
  2471 
 | 
| 
jcallahan@24
 | 
  2472         quest.races = quest.races or {}
 | 
| 
jcallahan@100
 | 
  2473         quest.races[(PLAYER_RACE == "Pandaren") and ("%s_%s"):format(PLAYER_RACE, PLAYER_FACTION or "Neutral") or PLAYER_RACE] = true
 | 
| 
jcallahan@10
 | 
  2474     end
 | 
| 
jcallahan@12
 | 
  2475 end -- do-block
 | 
| 
jcallahan@9
 | 
  2476 
 | 
| 
jcallahan@9
 | 
  2477 
 | 
| 
jcallahan@92
 | 
  2478 function WDP:QUEST_LOG_UPDATE(event_name)
 | 
| 
MMOSimca@581
 | 
  2479     local selected_quest = _G.C_QuestLog.GetSelectedQuest() -- Save current selection to be restored when we're done.
 | 
| 
jcallahan@36
 | 
  2480     local entry_index, processed_quests = 1, 0
 | 
| 
MMOSimca@581
 | 
  2481     local _, num_quests = _G.C_QuestLog.GetNumQuestLogEntries()
 | 
| 
jcallahan@36
 | 
  2482 
 | 
| 
jcallahan@36
 | 
  2483     while processed_quests <= num_quests do
 | 
| 
MMOSimca@581
 | 
  2484         local info = _G.C_QuestLog.GetInfo(entry_index)
 | 
| 
MMOSimca@581
 | 
  2485 
 | 
| 
MMOSimca@581
 | 
  2486         if info.questID == 0 then
 | 
| 
jcallahan@84
 | 
  2487             processed_quests = processed_quests + 1
 | 
| 
MMOSimca@581
 | 
  2488         elseif not info.isHeader then
 | 
| 
MMOSimca@581
 | 
  2489             _G.C_QuestLog.SetSelectedQuest(entry_index);
 | 
| 
MMOSimca@581
 | 
  2490 
 | 
| 
MMOSimca@581
 | 
  2491             local quest = DBEntry("quests", info.questID)
 | 
| 
jcallahan@36
 | 
  2492             quest.timer = _G.GetQuestLogTimeLeft()
 | 
| 
MMOSimca@581
 | 
  2493             quest.can_share = _G.C_QuestLog.IsPushableQuest(info.questID) and true or nil
 | 
| 
jcallahan@36
 | 
  2494             processed_quests = processed_quests + 1
 | 
| 
jcallahan@36
 | 
  2495         end
 | 
| 
jcallahan@36
 | 
  2496         entry_index = entry_index + 1
 | 
| 
jcallahan@36
 | 
  2497     end
 | 
| 
MMOSimca@581
 | 
  2498     _G.C_QuestLog.SetSelectedQuest(selected_quest)
 | 
| 
jcallahan@4
 | 
  2499     self:UnregisterEvent("QUEST_LOG_UPDATE")
 | 
| 
jcallahan@4
 | 
  2500 end
 | 
| 
jcallahan@4
 | 
  2501 
 | 
| 
jcallahan@4
 | 
  2502 
 | 
| 
jcallahan@97
 | 
  2503 function WDP:QUEST_PROGRESS(event_name)
 | 
| 
jcallahan@112
 | 
  2504     if not ALLOWED_LOCALES[CLIENT_LOCALE] then
 | 
| 
jcallahan@112
 | 
  2505         return
 | 
| 
jcallahan@112
 | 
  2506     end
 | 
| 
jcallahan@97
 | 
  2507     DBEntry("quests", _G.GetQuestID()).progress_text = ReplaceKeywords(_G.GetProgressText())
 | 
| 
jcallahan@97
 | 
  2508 end
 | 
| 
jcallahan@97
 | 
  2509 
 | 
| 
jcallahan@97
 | 
  2510 
 | 
| 
jcallahan@92
 | 
  2511 function WDP:UNIT_QUEST_LOG_CHANGED(event_name, unit_id)
 | 
| 
jcallahan@4
 | 
  2512     if unit_id ~= "player" then
 | 
| 
jcallahan@4
 | 
  2513         return
 | 
| 
jcallahan@4
 | 
  2514     end
 | 
| 
jcallahan@4
 | 
  2515     self:RegisterEvent("QUEST_LOG_UPDATE")
 | 
| 
jcallahan@4
 | 
  2516 end
 | 
| 
jcallahan@4
 | 
  2517 
 | 
| 
jcallahan@4
 | 
  2518 
 | 
| 
MMOSimca@581
 | 
  2519 -- This functionality is broken and should be rethought entirely in the wake of 10.0
 | 
| 
MMOSimca@581
 | 
  2520 --[[
 | 
| 
jcallahan@92
 | 
  2521 do
 | 
| 
jcallahan@92
 | 
  2522     local TRADESKILL_TOOLS = {
 | 
| 
jcallahan@92
 | 
  2523         Anvil = anvil_spell_ids,
 | 
| 
jcallahan@92
 | 
  2524         Forge = forge_spell_ids,
 | 
| 
jcallahan@92
 | 
  2525     }
 | 
| 
jcallahan@92
 | 
  2526 
 | 
| 
jcallahan@92
 | 
  2527 
 | 
| 
jcallahan@167
 | 
  2528     local function RegisterTools(tradeskill_name, tradeskill_index)
 | 
| 
catherton@479
 | 
  2529         local link = _G.C_TradeSkillUI.GetRecipeLink(tradeskill_index)
 | 
| 
catherton@465
 | 
  2530 
 | 
| 
MMOSimca@352
 | 
  2531         if link then
 | 
| 
MMOSimca@352
 | 
  2532             local spell_id = tonumber(link:match("^|c%x%x%x%x%x%x%x%x|H%w+:(%d+)"))
 | 
| 
catherton@479
 | 
  2533             local required_tool = _G.C_TradeSkillUI.GetRecipeTools(tradeskill_index)
 | 
| 
MMOSimca@352
 | 
  2534 
 | 
| 
MMOSimca@352
 | 
  2535             if required_tool then
 | 
| 
MMOSimca@352
 | 
  2536                 for tool_name, registry in pairs(TRADESKILL_TOOLS) do
 | 
| 
MMOSimca@352
 | 
  2537                     if required_tool:find(tool_name) then
 | 
| 
MMOSimca@352
 | 
  2538                         registry[spell_id] = true
 | 
| 
MMOSimca@352
 | 
  2539                     end
 | 
| 
jcallahan@167
 | 
  2540                 end
 | 
| 
jcallahan@167
 | 
  2541             end
 | 
| 
jcallahan@167
 | 
  2542         end
 | 
| 
jcallahan@167
 | 
  2543     end
 | 
| 
jcallahan@167
 | 
  2544 
 | 
| 
jcallahan@167
 | 
  2545 
 | 
| 
jcallahan@92
 | 
  2546     function WDP:TRADE_SKILL_SHOW(event_name)
 | 
| 
catherton@479
 | 
  2547         local profession_name, prof_level = _G.C_TradeSkillUI.GetTradeSkillLine()
 | 
| 
jcallahan@92
 | 
  2548 
 | 
| 
jcallahan@92
 | 
  2549         if profession_name == _G.UNKNOWN then
 | 
| 
jcallahan@92
 | 
  2550             return
 | 
| 
jcallahan@92
 | 
  2551         end
 | 
| 
jcallahan@167
 | 
  2552         TradeSkillExecutePer(RegisterTools)
 | 
| 
jcallahan@92
 | 
  2553     end
 | 
| 
jcallahan@92
 | 
  2554 end -- do-block
 | 
| 
jcallahan@92
 | 
  2555 
 | 
| 
jcallahan@92
 | 
  2556 
 | 
| 
jcallahan@167
 | 
  2557 function WDP:TRAINER_CLOSED(event_name)
 | 
| 
jcallahan@167
 | 
  2558     private.trainer_shown = nil
 | 
| 
jcallahan@167
 | 
  2559 end
 | 
| 
jcallahan@167
 | 
  2560 
 | 
| 
jcallahan@167
 | 
  2561 
 | 
| 
jcallahan@92
 | 
  2562 function WDP:TRAINER_SHOW(event_name)
 | 
| 
jcallahan@232
 | 
  2563     local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@164
 | 
  2564     local trainer = NPCEntry(unit_idnum)
 | 
| 
jcallahan@58
 | 
  2565 
 | 
| 
jcallahan@164
 | 
  2566     if not trainer then
 | 
| 
jcallahan@58
 | 
  2567         return
 | 
| 
jcallahan@58
 | 
  2568     end
 | 
| 
jcallahan@331
 | 
  2569     local _, trainer_standing = UnitFactionStanding("npc")
 | 
| 
jcallahan@164
 | 
  2570     trainer.teaches = trainer.teaches or {}
 | 
| 
jcallahan@27
 | 
  2571 
 | 
| 
jcallahan@167
 | 
  2572     private.trainer_shown = true
 | 
| 
jcallahan@167
 | 
  2573 
 | 
| 
jcallahan@27
 | 
  2574     -- Get the initial trainer filters
 | 
| 
MMOSimca@344
 | 
  2575     local available = _G.GetTrainerServiceTypeFilter("available") and 1 or 0
 | 
| 
MMOSimca@344
 | 
  2576     local unavailable = _G.GetTrainerServiceTypeFilter("unavailable") and 1 or 0
 | 
| 
MMOSimca@344
 | 
  2577     local used = _G.GetTrainerServiceTypeFilter("used") and 1 or 0
 | 
| 
jcallahan@27
 | 
  2578 
 | 
| 
jcallahan@27
 | 
  2579     -- Clear the trainer filters
 | 
| 
MMOSimca@344
 | 
  2580     _G.SetTrainerServiceTypeFilter("available", 1)
 | 
| 
MMOSimca@344
 | 
  2581     _G.SetTrainerServiceTypeFilter("unavailable", 1)
 | 
| 
MMOSimca@344
 | 
  2582     _G.SetTrainerServiceTypeFilter("used", 1)
 | 
| 
jcallahan@27
 | 
  2583 
 | 
| 
jcallahan@27
 | 
  2584     for index = 1, _G.GetNumTrainerServices(), 1 do
 | 
| 
jcallahan@27
 | 
  2585         local spell_name, rank_name, _, _, required_level = _G.GetTrainerServiceInfo(index)
 | 
| 
jcallahan@27
 | 
  2586 
 | 
| 
jcallahan@27
 | 
  2587         if spell_name then
 | 
| 
jcallahan@27
 | 
  2588             DatamineTT:ClearLines()
 | 
| 
jcallahan@27
 | 
  2589             DatamineTT:SetTrainerService(index)
 | 
| 
jcallahan@27
 | 
  2590 
 | 
| 
atcaleb@570
 | 
  2591             local _, spell_id = DatamineTT:GetSpell()
 | 
| 
jcallahan@27
 | 
  2592 
 | 
| 
jcallahan@43
 | 
  2593             if spell_id then
 | 
| 
jcallahan@164
 | 
  2594                 local class_professions = trainer.teaches[PLAYER_CLASS]
 | 
| 
jcallahan@164
 | 
  2595 
 | 
| 
jcallahan@164
 | 
  2596                 if not class_professions then
 | 
| 
jcallahan@164
 | 
  2597                     trainer.teaches[PLAYER_CLASS] = {}
 | 
| 
jcallahan@164
 | 
  2598                     class_professions = trainer.teaches[PLAYER_CLASS]
 | 
| 
jcallahan@164
 | 
  2599                 end
 | 
| 
jcallahan@43
 | 
  2600                 local profession, min_skill = _G.GetTrainerServiceSkillReq(index)
 | 
| 
jcallahan@43
 | 
  2601                 profession = profession or "General"
 | 
| 
jcallahan@43
 | 
  2602 
 | 
| 
jcallahan@164
 | 
  2603                 local profession_skills = class_professions[profession]
 | 
| 
jcallahan@43
 | 
  2604 
 | 
| 
jcallahan@43
 | 
  2605                 if not profession_skills then
 | 
| 
jcallahan@43
 | 
  2606                     class_professions[profession] = {}
 | 
| 
jcallahan@43
 | 
  2607                     profession_skills = class_professions[profession]
 | 
| 
jcallahan@43
 | 
  2608                 end
 | 
| 
jcallahan@173
 | 
  2609                 profession_skills[spell_id] = ("%d:%d:%d"):format(required_level, min_skill, _G.GetTrainerServiceCost(index))
 | 
| 
jcallahan@27
 | 
  2610             end
 | 
| 
jcallahan@27
 | 
  2611         end
 | 
| 
jcallahan@27
 | 
  2612     end
 | 
| 
jcallahan@27
 | 
  2613     -- Reset the filters to what they were before
 | 
| 
MMOSimca@344
 | 
  2614     _G.SetTrainerServiceTypeFilter("available", available or 0)
 | 
| 
MMOSimca@344
 | 
  2615     _G.SetTrainerServiceTypeFilter("unavailable", unavailable or 0)
 | 
| 
MMOSimca@344
 | 
  2616     _G.SetTrainerServiceTypeFilter("used", used or 0)
 | 
| 
jcallahan@27
 | 
  2617 end
 | 
| 
MMOSimca@581
 | 
  2618 ]]--
 | 
| 
jcallahan@27
 | 
  2619 
 | 
| 
jcallahan@27
 | 
  2620 
 | 
| 
jcallahan@1
 | 
  2621 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)
 | 
| 
jcallahan@1
 | 
  2622     if private.tracked_line or unit_id ~= "player" then
 | 
| 
jcallahan@1
 | 
  2623         return
 | 
| 
jcallahan@1
 | 
  2624     end
 | 
| 
jcallahan@1
 | 
  2625     local spell_label = private.SPELL_LABELS_BY_NAME[spell_name]
 | 
| 
jcallahan@1
 | 
  2626 
 | 
| 
jcallahan@1
 | 
  2627     if not spell_label then
 | 
| 
jcallahan@1
 | 
  2628         return
 | 
| 
jcallahan@1
 | 
  2629     end
 | 
| 
jcallahan@306
 | 
  2630 
 | 
| 
MMOSimca@343
 | 
  2631     Debug("UNIT_SPELLCAST_SENT: %s was cast.", spell_name)
 | 
| 
jcallahan@150
 | 
  2632     local item_name, item_link = _G.GameTooltip:GetItem()
 | 
| 
jcallahan@150
 | 
  2633     local unit_name, unit_id = _G.GameTooltip:GetUnit()
 | 
| 
jcallahan@1
 | 
  2634 
 | 
| 
jcallahan@150
 | 
  2635     if not unit_name and _G.UnitName("target") == target_name then
 | 
| 
jcallahan@150
 | 
  2636         unit_name = target_name
 | 
| 
jcallahan@150
 | 
  2637         unit_id = "target"
 | 
| 
jcallahan@1
 | 
  2638     end
 | 
| 
jcallahan@1
 | 
  2639     local spell_flags = private.SPELL_FLAGS_BY_LABEL[spell_label]
 | 
| 
jcallahan@28
 | 
  2640     local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
 | 
| 
MMOSimca@328
 | 
  2641     if not (zone_name and area_id and x and y and map_level) then
 | 
| 
mmosimca@508
 | 
  2642         if not (_G.IsInInstance()) then
 | 
| 
mmosimca@508
 | 
  2643             Debug("%s: Missing current location data - %s, %s, %s, %s, %s.", event_name, tostring(zone_name), tostring(area_id), tostring(x), tostring(y), tostring(map_level))
 | 
| 
mmosimca@508
 | 
  2644         end
 | 
| 
MMOSimca@328
 | 
  2645         return
 | 
| 
MMOSimca@328
 | 
  2646     end
 | 
| 
jcallahan@28
 | 
  2647 
 | 
| 
jcallahan@205
 | 
  2648     table.wipe(current_action)
 | 
| 
jcallahan@122
 | 
  2649     current_action.instance_token = instance_token
 | 
| 
jcallahan@122
 | 
  2650     current_action.map_level = map_level
 | 
| 
jcallahan@122
 | 
  2651     current_action.x = x
 | 
| 
jcallahan@122
 | 
  2652     current_action.y = y
 | 
| 
jcallahan@122
 | 
  2653     current_action.zone_data = ("%s:%d"):format(zone_name, area_id)
 | 
| 
jcallahan@122
 | 
  2654     current_action.spell_label = spell_label
 | 
| 
jcallahan@105
 | 
  2655 
 | 
| 
jcallahan@105
 | 
  2656     if not private.NON_LOOT_SPELL_LABELS[spell_label] then
 | 
| 
jcallahan@122
 | 
  2657         current_action.loot_label = spell_label:lower()
 | 
| 
jcallahan@105
 | 
  2658     end
 | 
| 
jcallahan@1
 | 
  2659 
 | 
| 
jcallahan@151
 | 
  2660     if unit_name and unit_name == target_name and not item_name then
 | 
| 
jcallahan@16
 | 
  2661         if bit.band(spell_flags, AF.NPC) == AF.NPC then
 | 
| 
jcallahan@150
 | 
  2662             if not unit_id or unit_name ~= target_name then
 | 
| 
jcallahan@16
 | 
  2663                 return
 | 
| 
jcallahan@16
 | 
  2664             end
 | 
| 
jcallahan@123
 | 
  2665             current_action.target_type = AF.NPC
 | 
| 
jcallahan@16
 | 
  2666         end
 | 
| 
jcallahan@16
 | 
  2667     elseif bit.band(spell_flags, AF.ITEM) == AF.ITEM then
 | 
| 
jcallahan@123
 | 
  2668         current_action.target_type = AF.ITEM
 | 
| 
jcallahan@16
 | 
  2669 
 | 
| 
jcallahan@150
 | 
  2670         if item_name and item_name == target_name then
 | 
| 
jcallahan@150
 | 
  2671             current_action.identifier = ItemLinkToID(item_link)
 | 
| 
jcallahan@16
 | 
  2672         elseif target_name and target_name ~= "" then
 | 
| 
jcallahan@331
 | 
  2673             local _, item_link = _G.GetItemInfo(target_name)
 | 
| 
jcallahan@331
 | 
  2674             current_action.identifier = ItemLinkToID(item_link)
 | 
| 
jcallahan@16
 | 
  2675         end
 | 
| 
jcallahan@150
 | 
  2676     elseif not item_name and not unit_name then
 | 
| 
jcallahan@1
 | 
  2677         if bit.band(spell_flags, AF.OBJECT) == AF.OBJECT then
 | 
| 
jcallahan@17
 | 
  2678             if target_name == "" then
 | 
| 
jcallahan@17
 | 
  2679                 return
 | 
| 
jcallahan@17
 | 
  2680             end
 | 
| 
jcallahan@122
 | 
  2681             current_action.object_name = target_name
 | 
| 
jcallahan@123
 | 
  2682             current_action.target_type = AF.OBJECT
 | 
| 
jcallahan@1
 | 
  2683         elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then
 | 
| 
jcallahan@123
 | 
  2684             current_action.target_type = AF.ZONE
 | 
| 
jcallahan@1
 | 
  2685         end
 | 
| 
jcallahan@1
 | 
  2686     end
 | 
| 
jcallahan@1
 | 
  2687     private.tracked_line = spell_line
 | 
| 
jcallahan@0
 | 
  2688 end
 | 
| 
jcallahan@0
 | 
  2689 
 | 
| 
jcallahan@94
 | 
  2690 
 | 
| 
MMOSimca@393
 | 
  2691 -- Triggered by bonus roll prompts, disenchant prompts, and in a few other rare circumstances
 | 
| 
jcallahan@312
 | 
  2692 function WDP:SPELL_CONFIRMATION_PROMPT(event_name, spell_id, confirm_type, text, duration, currency_id_cost)
 | 
| 
jcallahan@306
 | 
  2693     if private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id] then
 | 
| 
jcallahan@306
 | 
  2694         ClearKilledBossID()
 | 
| 
jcallahan@306
 | 
  2695         ClearLootToastContainerID()
 | 
| 
MMOSimca@387
 | 
  2696         raid_boss_id = private.RAID_BOSS_BONUS_SPELL_ID_TO_NPC_ID_MAP[spell_id]
 | 
| 
jcallahan@306
 | 
  2697     else
 | 
| 
MMOSimca@336
 | 
  2698         Debug("%s: Spell ID %d is not a known raid boss 'Bonus' spell.", event_name, spell_id)
 | 
| 
jcallahan@306
 | 
  2699         return
 | 
| 
jcallahan@1
 | 
  2700     end
 | 
| 
jcallahan@306
 | 
  2701 
 | 
| 
jcallahan@324
 | 
  2702     -- Assign existing loot data to boss if it exists
 | 
| 
jcallahan@307
 | 
  2703     if loot_toast_data then
 | 
| 
MMOSimca@427
 | 
  2704         local npc = NPCEntry(raid_boss_id)
 | 
| 
MMOSimca@427
 | 
  2705         if npc then
 | 
| 
MMOSimca@427
 | 
  2706             -- Create needed npc fields if required
 | 
| 
MMOSimca@427
 | 
  2707             local loot_label = "drops"
 | 
| 
MMOSimca@427
 | 
  2708             local encounter_data = npc:EncounterData(InstanceDifficultyToken())
 | 
| 
MMOSimca@427
 | 
  2709             encounter_data[loot_label] = encounter_data[loot_label] or {}
 | 
| 
MMOSimca@427
 | 
  2710             encounter_data.loot_counts = encounter_data.loot_counts or {}
 | 
| 
MMOSimca@427
 | 
  2711 
 | 
| 
MMOSimca@427
 | 
  2712             for index = 1, #loot_toast_data do
 | 
| 
MMOSimca@427
 | 
  2713                 local data = loot_toast_data[index]
 | 
| 
MMOSimca@427
 | 
  2714                 local loot_type = data[1]
 | 
| 
MMOSimca@427
 | 
  2715                 local hyperlink = data[2]
 | 
| 
MMOSimca@427
 | 
  2716                 local quantity = data[3]
 | 
| 
MMOSimca@427
 | 
  2717 
 | 
| 
MMOSimca@427
 | 
  2718                 if loot_type == "item" then
 | 
| 
MMOSimca@427
 | 
  2719                     local item_id = ItemLinkToID(hyperlink)
 | 
| 
MMOSimca@427
 | 
  2720                     Debug("%s: Assigned stored item loot data - %s - %d:%d", event_name, hyperlink, item_id, quantity)
 | 
| 
MMOSimca@427
 | 
  2721                     table.insert(encounter_data[loot_label], ("%d:%d"):format(item_id, quantity))
 | 
| 
MMOSimca@427
 | 
  2722                 elseif loot_type == "money" then
 | 
| 
MMOSimca@427
 | 
  2723                     Debug("%s: Assigned stored money loot data - money:%d", event_name, quantity)
 | 
| 
MMOSimca@427
 | 
  2724                     table.insert(encounter_data[loot_label], ("money:%d"):format(quantity))
 | 
| 
MMOSimca@427
 | 
  2725                 elseif loot_type == "currency" then
 | 
| 
mmosimca@496
 | 
  2726                     local currency_id = CurrencyLinkToID(hyperlink)
 | 
| 
mmosimca@496
 | 
  2727                     Debug("%s: Assigned stored currency loot data - %s - currency:%d (%d)", event_name, hyperlink, currency_id, quantity)
 | 
| 
mmosimca@496
 | 
  2728                     table.insert(encounter_data[loot_label], ("currency:%d:%d"):format(quantity, currency_id))
 | 
| 
MMOSimca@427
 | 
  2729                 end
 | 
| 
jcallahan@317
 | 
  2730             end
 | 
| 
jcallahan@317
 | 
  2731 
 | 
| 
MMOSimca@427
 | 
  2732             if not boss_loot_toasting[raid_boss_id] then
 | 
| 
MMOSimca@427
 | 
  2733                 encounter_data.loot_counts[loot_label] = (encounter_data.loot_counts[loot_label] or 0) + 1
 | 
| 
MMOSimca@427
 | 
  2734                 boss_loot_toasting[raid_boss_id] = true -- Do not count further loots until timer expires or another boss is killed
 | 
| 
jcallahan@307
 | 
  2735             end
 | 
| 
MMOSimca@427
 | 
  2736         else
 | 
| 
MMOSimca@427
 | 
  2737             Debug("%s: NPC is nil, but we have stored loot data...", event_name)
 | 
| 
jcallahan@307
 | 
  2738         end
 | 
| 
jcallahan@307
 | 
  2739     end
 | 
| 
jcallahan@307
 | 
  2740 
 | 
| 
jcallahan@307
 | 
  2741     ClearLootToastData()
 | 
| 
MMOSimca@427
 | 
  2742     killed_boss_id_timer_handle = C_Timer.NewTimer(5, ClearKilledBossID)
 | 
| 
jcallahan@306
 | 
  2743 end
 | 
| 
jcallahan@306
 | 
  2744 
 | 
| 
jcallahan@306
 | 
  2745 
 | 
| 
jcallahan@306
 | 
  2746 function WDP:UNIT_SPELLCAST_SUCCEEDED(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
 | 
| 
jcallahan@306
 | 
  2747     if unit_id ~= "player" then
 | 
| 
jcallahan@306
 | 
  2748         return
 | 
| 
jcallahan@306
 | 
  2749     end
 | 
| 
jcallahan@306
 | 
  2750     private.tracked_line = nil
 | 
| 
jcallahan@306
 | 
  2751     private.previous_spell_id = spell_id
 | 
| 
jcallahan@306
 | 
  2752 
 | 
| 
MMOSimca@393
 | 
  2753     -- For spells cast when Logging
 | 
| 
MMOSimca@345
 | 
  2754     if private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id] then
 | 
| 
MMOSimca@345
 | 
  2755         last_timber_spell_id = spell_id
 | 
| 
MMOSimca@351
 | 
  2756         UpdateDBEntryLocation("objects", ("OPENING:%s"):format(private.LOGGING_SPELL_ID_TO_OBJECT_ID_MAP[spell_id]))
 | 
| 
MMOSimca@345
 | 
  2757         return
 | 
| 
MMOSimca@345
 | 
  2758     end
 | 
| 
MMOSimca@345
 | 
  2759 
 | 
| 
MMOSimca@393
 | 
  2760     -- For spells cast by items that always trigger loot toasts
 | 
| 
MMOSimca@381
 | 
  2761     if private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id] then
 | 
| 
jcallahan@306
 | 
  2762         ClearKilledBossID()
 | 
| 
jcallahan@306
 | 
  2763         ClearLootToastContainerID()
 | 
| 
jcallahan@307
 | 
  2764         ClearLootToastData()
 | 
| 
jcallahan@306
 | 
  2765 
 | 
| 
MMOSimca@387
 | 
  2766         loot_toast_container_id = private.LOOT_TOAST_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
 | 
| 
MMOSimca@383
 | 
  2767         loot_toast_container_timer_handle = C_Timer.NewTimer(1, ClearLootToastContainerID) -- we need to assign a handle here to cancel it later
 | 
| 
MMOSimca@345
 | 
  2768         return
 | 
| 
jcallahan@306
 | 
  2769     end
 | 
| 
jcallahan@306
 | 
  2770 
 | 
| 
MMOSimca@393
 | 
  2771     -- For spells cast by items that don't usually trigger loot toasts
 | 
| 
catherton@473
 | 
  2772     if not block_chat_loot_data and (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id] or (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id] and private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID])) then
 | 
| 
MMOSimca@347
 | 
  2773         -- Set up timer
 | 
| 
MMOSimca@393
 | 
  2774         ClearChatLootData()
 | 
| 
MMOSimca@393
 | 
  2775         Debug("%s: Beginning chat-based loot timer for spellID %d", event_name, spell_id)
 | 
| 
MMOSimca@411
 | 
  2776         chat_loot_timer_handle = C_Timer.NewTimer(1.5, ClearChatLootData)
 | 
| 
catherton@473
 | 
  2777         if (private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id] and private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID]) then
 | 
| 
catherton@473
 | 
  2778             chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_BY_CLASS_ID_MAP[spell_id][PLAYER_CLASS_ID]
 | 
| 
MMOSimca@454
 | 
  2779         else
 | 
| 
MMOSimca@454
 | 
  2780             chat_loot_data.identifier = private.DELAYED_CONTAINER_SPELL_ID_TO_ITEM_ID_MAP[spell_id]
 | 
| 
MMOSimca@454
 | 
  2781         end
 | 
| 
MMOSimca@347
 | 
  2782         return
 | 
| 
MMOSimca@347
 | 
  2783     end
 | 
| 
MMOSimca@347
 | 
  2784 
 | 
| 
mmosimca@520
 | 
  2785     -- For Ephemeral Crystals (uses a combination of mouseover text and a 'Update Interactions' spell cast to detect the object - this is incredibly hacky but there is no alternative)
 | 
| 
mmosimca@520
 | 
  2786     local text = _G["GameTooltipTextLeft1"] and _G["GameTooltipTextLeft1"]:GetText() or nil
 | 
| 
mmosimca@520
 | 
  2787     if spell_id == SPELL_ID_UPDATE_INTERACTIONS and text and text == "Ephemeral Crystal" then
 | 
| 
mmosimca@522
 | 
  2788         Debug("%s: Detected location for an Ephemeral Crystal.", event_name)
 | 
| 
mmosimca@520
 | 
  2789         for index = 1, #private.EPHEMERAL_CRYSTAL_OBJECT_IDS do
 | 
| 
mmosimca@520
 | 
  2790             UpdateDBEntryLocation("objects", private.EPHEMERAL_CRYSTAL_OBJECT_IDS[index])
 | 
| 
mmosimca@520
 | 
  2791         end
 | 
| 
mmosimca@520
 | 
  2792     end
 | 
| 
mmosimca@520
 | 
  2793 
 | 
| 
jcallahan@306
 | 
  2794     if anvil_spell_ids[spell_id] then
 | 
| 
jcallahan@306
 | 
  2795         UpdateDBEntryLocation("objects", OBJECT_ID_ANVIL)
 | 
| 
jcallahan@306
 | 
  2796     elseif forge_spell_ids[spell_id] then
 | 
| 
jcallahan@306
 | 
  2797         UpdateDBEntryLocation("objects", OBJECT_ID_FORGE)
 | 
| 
jcallahan@306
 | 
  2798     elseif spell_name:match("^Harvest.+") then
 | 
| 
jcallahan@306
 | 
  2799         killed_npc_id = current_target_id
 | 
| 
MMOSimca@343
 | 
  2800         private.harvesting = true -- Used to track which NPCs can be harvested (can we get this from CreatureCache instead?)
 | 
| 
jcallahan@306
 | 
  2801     end
 | 
| 
jcallahan@306
 | 
  2802 end
 | 
| 
jcallahan@0
 | 
  2803 
 | 
| 
jcallahan@90
 | 
  2804 
 | 
| 
jcallahan@1
 | 
  2805 function WDP:HandleSpellFailure(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
 | 
| 
jcallahan@1
 | 
  2806     if unit_id ~= "player" then
 | 
| 
jcallahan@1
 | 
  2807         return
 | 
| 
jcallahan@1
 | 
  2808     end
 | 
| 
jcallahan@0
 | 
  2809 
 | 
| 
jcallahan@1
 | 
  2810     if private.tracked_line == spell_line then
 | 
| 
jcallahan@1
 | 
  2811         private.tracked_line = nil
 | 
| 
jcallahan@1
 | 
  2812     end
 | 
| 
jcallahan@147
 | 
  2813     table.wipe(current_action)
 | 
| 
jcallahan@0
 | 
  2814 end
 | 
| 
jcallahan@90
 | 
  2815 
 | 
| 
jcallahan@90
 | 
  2816 
 | 
| 
jcallahan@90
 | 
  2817 do
 | 
| 
jcallahan@90
 | 
  2818     local function SetUnitField(field, required_type)
 | 
| 
jcallahan@90
 | 
  2819         local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@90
 | 
  2820 
 | 
| 
jcallahan@90
 | 
  2821         if not unit_idnum or (required_type and unit_type ~= required_type) then
 | 
| 
jcallahan@90
 | 
  2822             return
 | 
| 
jcallahan@90
 | 
  2823         end
 | 
| 
jcallahan@90
 | 
  2824 
 | 
| 
jcallahan@171
 | 
  2825         if UnitTypeIsNPC(unit_type) then
 | 
| 
jcallahan@90
 | 
  2826             NPCEntry(unit_idnum)[field] = true
 | 
| 
jcallahan@90
 | 
  2827         elseif unit_type == private.UNIT_TYPES.OBJECT then
 | 
| 
jcallahan@90
 | 
  2828             DBEntry("objects", unit_idnum)[field] = true
 | 
| 
jcallahan@93
 | 
  2829             UpdateDBEntryLocation("objects", unit_idnum)
 | 
| 
jcallahan@90
 | 
  2830         end
 | 
| 
jcallahan@90
 | 
  2831     end
 | 
| 
jcallahan@90
 | 
  2832 
 | 
| 
jcallahan@90
 | 
  2833 
 | 
| 
jcallahan@90
 | 
  2834     function WDP:AUCTION_HOUSE_SHOW(event_name)
 | 
| 
MMOSimca@436
 | 
  2835         WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@90
 | 
  2836         SetUnitField("auctioneer", private.UNIT_TYPES.NPC)
 | 
| 
jcallahan@90
 | 
  2837     end
 | 
| 
jcallahan@90
 | 
  2838 
 | 
| 
jcallahan@90
 | 
  2839 
 | 
| 
MMOSimca@581
 | 
  2840 	-- manager_frame_id is 4 in case we need to merge this into that event
 | 
| 
jcallahan@90
 | 
  2841     function WDP:BANKFRAME_OPENED(event_name)
 | 
| 
MMOSimca@436
 | 
  2842         WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@90
 | 
  2843         SetUnitField("banker", private.UNIT_TYPES.NPC)
 | 
| 
jcallahan@90
 | 
  2844     end
 | 
| 
jcallahan@90
 | 
  2845 
 | 
| 
jcallahan@90
 | 
  2846 
 | 
| 
jcallahan@90
 | 
  2847     function WDP:BATTLEFIELDS_SHOW(event_name)
 | 
| 
jcallahan@90
 | 
  2848         SetUnitField("battlemaster", private.UNIT_TYPES.NPC)
 | 
| 
jcallahan@90
 | 
  2849     end
 | 
| 
jcallahan@90
 | 
  2850 
 | 
| 
jcallahan@90
 | 
  2851 
 | 
| 
jcallahan@323
 | 
  2852     local GOSSIP_SHOW_FUNCS = {
 | 
| 
jcallahan@323
 | 
  2853         [private.UNIT_TYPES.NPC] = function(unit_idnum)
 | 
| 
MMOSimca@581
 | 
  2854             local gossip_options = { _G.C_GossipInfo.GetOptions() }
 | 
| 
jcallahan@323
 | 
  2855 
 | 
| 
jcallahan@323
 | 
  2856             for index = 2, #gossip_options, 2 do
 | 
| 
jcallahan@323
 | 
  2857                 if gossip_options[index] == "binder" then
 | 
| 
jcallahan@323
 | 
  2858                     SetUnitField("innkeeper", private.UNIT_TYPES.NPC)
 | 
| 
jcallahan@323
 | 
  2859                     return
 | 
| 
jcallahan@323
 | 
  2860                 end
 | 
| 
jcallahan@323
 | 
  2861             end
 | 
| 
jcallahan@323
 | 
  2862         end,
 | 
| 
jcallahan@323
 | 
  2863         [private.UNIT_TYPES.OBJECT] = function(unit_idnum)
 | 
| 
jcallahan@323
 | 
  2864             UpdateDBEntryLocation("objects", unit_idnum)
 | 
| 
jcallahan@323
 | 
  2865         end,
 | 
| 
jcallahan@323
 | 
  2866     }
 | 
| 
jcallahan@323
 | 
  2867 
 | 
| 
jcallahan@323
 | 
  2868 
 | 
| 
MMOSimca@581
 | 
  2869 	-- manager_frame_id is 3 in case we need to merge this into that event
 | 
| 
jcallahan@92
 | 
  2870     function WDP:GOSSIP_SHOW(event_name)
 | 
| 
MMOSimca@436
 | 
  2871         WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@323
 | 
  2872         local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
 | 
| 
jcallahan@323
 | 
  2873         if not unit_idnum then
 | 
| 
jcallahan@323
 | 
  2874             return
 | 
| 
jcallahan@323
 | 
  2875         end
 | 
| 
jcallahan@323
 | 
  2876 
 | 
| 
jcallahan@323
 | 
  2877         if GOSSIP_SHOW_FUNCS[unit_type] then
 | 
| 
jcallahan@323
 | 
  2878             GOSSIP_SHOW_FUNCS[unit_type](unit_idnum)
 | 
| 
jcallahan@90
 | 
  2879         end
 | 
| 
jcallahan@90
 | 
  2880     end
 | 
| 
jcallahan@90
 | 
  2881 
 | 
| 
jcallahan@90
 | 
  2882 
 | 
| 
MMOSimca@581
 | 
  2883 	-- manager_frame_id is 10 in case we need to merge this into that event
 | 
| 
jcallahan@93
 | 
  2884     function WDP:GUILDBANKFRAME_OPENED(event_name)
 | 
| 
MMOSimca@436
 | 
  2885         WDP:StopChatLootRecording(event_name)
 | 
| 
jcallahan@93
 | 
  2886         SetUnitField("guild_bank", private.UNIT_TYPES.OBJECT)
 | 
| 
jcallahan@93
 | 
  2887     end
 | 
| 
jcallahan@93
 | 
  2888 
 | 
| 
jcallahan@93
 | 
  2889 
 | 
| 
MMOSimca@581
 | 
  2890 	-- manager_frame_id is 6 in case we need to merge this into that event
 | 
| 
jcallahan@90
 | 
  2891     function WDP:TAXIMAP_OPENED(event_name)
 | 
| 
jcallahan@90
 | 
  2892         SetUnitField("flight_master", private.UNIT_TYPES.NPC)
 | 
| 
jcallahan@90
 | 
  2893     end
 | 
| 
jcallahan@90
 | 
  2894 
 | 
| 
jcallahan@90
 | 
  2895 
 | 
| 
MMOSimca@581
 | 
  2896     function WDP:PLAYER_INTERACTION_MANAGER_FRAME_SHOW(event_name, manager_frame_id)
 | 
| 
MMOSimca@581
 | 
  2897 		if not manager_frame_id then
 | 
| 
MMOSimca@581
 | 
  2898 			return
 | 
| 
MMOSimca@581
 | 
  2899 		elseif manager_frame_id == 24 then
 | 
| 
MMOSimca@581
 | 
  2900 			SetUnitField("transmogrifier", private.UNIT_TYPES.NPC)
 | 
| 
MMOSimca@581
 | 
  2901 		elseif manager_frame_id == 26 then
 | 
| 
MMOSimca@581
 | 
  2902 			WDP:StopChatLootRecording(event_name)
 | 
| 
MMOSimca@581
 | 
  2903 			SetUnitField("void_storage", private.UNIT_TYPES.NPC)
 | 
| 
MMOSimca@581
 | 
  2904 		elseif manager_frame_id == 53 then
 | 
| 
MMOSimca@581
 | 
  2905 			WDP:StopChatLootRecording(event_name)
 | 
| 
MMOSimca@581
 | 
  2906 			SetUnitField("item_upgrade_master", private.UNIT_TYPES.NPC)
 | 
| 
MMOSimca@581
 | 
  2907 		end
 | 
| 
jcallahan@90
 | 
  2908     end
 | 
| 
jcallahan@90
 | 
  2909 end -- do-block
 |