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