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