-- extra info on GameTooltip and ItemRefTooltip local AL = AceLibrary("AceLocale-2.2"):new("AtlasLoot") local AtlasLootTip = CreateFrame("Frame", "AtlasLootTip", GameTooltip) local strfind = string.find local GetItemInfo = GetItemInfo local GREY = "|cff999999" local WrappingLines = { ["Set: %s"] = gsub("^"..ITEM_SET_BONUS, " %%s", ""), ["(%d) Set: %s"] = gsub(gsub(ITEM_SET_BONUS_GRAY, "%(%%d%)", "^%%(%%d%%)"), " %%s", ""), ["Effect: %s"] = gsub("^"..ITEM_SPELL_EFFECT, " %%s", ""), ["Equip:"] = "^"..ITEM_SPELL_TRIGGER_ONEQUIP, ["Chance on hit:"] = "^"..ITEM_SPELL_TRIGGER_ONPROC, ["Use:"] = "^"..ITEM_SPELL_TRIGGER_ONUSE, } local lines = {} for i = 1, 30 do lines[i] = {} end local function AddSourceLine(tooltip, sourceStr) local name = tooltip:GetName() local numLines = tooltip:NumLines() local left, right local leftText, rightText local rL, gL, bL local rR, gR, bR local wrap for i in pairs(lines) do for j in pairs(lines[i]) do lines[i][j] = nil end end for i = 1, numLines do left = getglobal(name .. "TextLeft" .. i) right = getglobal(name .. "TextRight" .. i) leftText = left:GetText() rightText = right:IsShown() and right:GetText() rL, gL, bL = left:GetTextColor() rR, gR, bR = right:GetTextColor() lines[i][1] = leftText lines[i][2] = rightText lines[i][3] = rL lines[i][4] = gL lines[i][5] = bL lines[i][6] = rR lines[i][7] = gR lines[i][8] = bR end if not lines[1][1] then return end tooltip:SetText(lines[1][1], lines[1][3], lines[1][4], lines[1][5], 1, false) if numLines < 28 then tooltip:AddLine(sourceStr) elseif lines[2][1] then lines[2][1] = sourceStr.."\n"..lines[2][1] end for i = 2, getn(lines) do if lines[i][2] then tooltip:AddDoubleLine(lines[i][1], lines[i][2], lines[i][3], lines[i][4], lines[i][5], lines[i][6], lines[i][7], lines[i][8]) else wrap = false if strsub(lines[i][1] or "", 1, 1) == "\"" then wrap = true else for _, pattern in pairs(WrappingLines) do if strfind(lines[i][1] or "", pattern) then wrap = true break end end end tooltip:AddLine(lines[i][1], lines[i][3], lines[i][4], lines[i][5], wrap) end end tooltip:Show() end local sets = { ["SpiritofEskhandar"] = true, ["HakkariBlades"] = true, ["PrimalBlessing"] = true, ["ShardOfGods"] = true, ["DalRend"] = true, ["SpiderKiss"] = true, ["UnobMounts"] = true, ["Legendaries"] = true, ["Artifacts"] = true, ["ZGRings"] = true, ["Tabards"] = true, } local professions = { ["Apprentice"] = true, ["Journeyman"] = true, ["Expert"] = true, ["Artisan"] = true, ["Goblin"] = true, ["Gnomish"] = true, ["Survival"] = true, ["Herbalism"] = true, ["FirstAid"] = true, ["Poisons"] = true, ["Mining"] = true, ["Smelting"] = true, ["Elemental"] = true, ["Tribal"] = true, ["Dragonscale"] = true, ["Weaponsmith"] = true, ["Axesmith"] = true, ["Hammersmith"] = true, ["Swordsmith"] = true, ["Armorsmith"] = true, ["Gemology"] = true, ["Goldsmithing"] = true, } local function SetPartialMatch(set, str) if type(set) ~= "table" then return end for k in pairs(set) do if strfind(str, k, 1, true) then return k end end end local function SetContains(set, key) if not set or not key then return false end return set[key] ~= nil end local lastItemID, lastSourceStr, lastDropRate local function ExtendTooltip(tooltip) if not AtlasLootCharDB.ShowSource then return end local tooltipName = tooltip:GetName() local line2 = getglobal(tooltipName .. "TextLeft2") local craftSpell, source, sourceStr, dropRate local isCraft, isWBLoot, isPvP, isRepReward, isSetPiece, isWorldEvent = false, false, false, false, false, false local itemID = tonumber(tooltip.itemID) if itemID and itemID ~= 51217 then -- 51217 Fashion Coin if itemID ~= lastItemID then for row = 1, tooltip:NumLines() do local rowtext = getglobal(tooltipName.."TextLeft"..row):GetText() -- skip items that state which rep they require if strfind(rowtext or "", "—", 1, true) then return end end -- first check if its craftable item for k,v in pairs(GetSpellInfoAtlasLootDB["craftspells"]) do if v["craftItem"] == itemID then craftSpell = "s"..tostring(k) break end end for k, v in pairs(GetSpellInfoAtlasLootDB["enchants"]) do if v["item"] and v["item"] == itemID then craftSpell = "e"..tostring(k) break end end for k1, v1 in pairs(AtlasLoot_Data["AtlasLootCrafting"]) do if source then break end for k2, v2 in pairs(AtlasLoot_Data["AtlasLootCrafting"][k1]) do if v2[1] ~= 0 and v2[1] ~= "" then if (v2[1] == craftSpell or v2[1] == itemID) and SetPartialMatch(professions, k1) then source = k1 isCraft = true dropRate = AtlasLoot_FixText(v2[4] or "") or "" dropRate = gsub(dropRate or "", "\124cff%x%x%x%x%x%x", "") local skill = "" _, _, dropRate, skill = strfind(dropRate or "", "("..AL["Skill:"]..") (%d+)") if dropRate and skill then dropRate = skill ~= "300" and dropRate.." "..skill.."+" or dropRate.." "..skill lastDropRate = dropRate else lastDropRate = nil end break end end end end -- check if its world boss loot if not isCraft then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootWBItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootWBItems"][k1]) do if v2[1] == itemID then source = k1 isWBLoot = true if v2[5] and v2[5] ~= "" then dropRate = v2[5] lastDropRate = dropRate else lastDropRate = nil end break end end end end -- check if its a pvp reward if not isCraft and not isWBLoot then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootGeneralPvPItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootGeneralPvPItems"][k1]) do if v2[1] == itemID then source = k1 isPvP = true lastDropRate = nil break end end end end -- check if its a rep reward -- bgs if not isCraft and not isWBLoot and not isPvP then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootBGItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootBGItems"][k1]) do if v2[1] == itemID then source = k1 isRepReward = true if v2[5] and v2[5] ~= "" then dropRate = v2[5] lastDropRate = dropRate else lastDropRate = nil end break end end end -- factions for k1,v1 in pairs(AtlasLoot_Data["AtlasLootRepItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootRepItems"][k1]) do if v2[1] == itemID then source = k1 isRepReward = true if v2[5] and v2[5] ~= "" --[[and source ~= "Darkmoon" and not strfind(source, "Cenarion",1,true)]] then dropRate = v2[5] lastDropRate = dropRate else lastDropRate = nil end break end end end end -- check if its a set piece if not isCraft and not isWBLoot and not isPvP and not isRepReward then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootSetItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootSetItems"][k1]) do if v2[1] == itemID then source = k1 isSetPiece = true if (SetContains(sets, source) or strfind(source, "WorldEpics",1,true)) then source = nil isSetPiece = false end lastDropRate = nil break end end end end -- check world events if not isCraft and not isWBLoot and not isPvP and not isRepReward and not isSetPiece then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootWorldEvents"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootWorldEvents"][k1]) do if v2[1] == itemID then source = k1 isWorldEvent = true if v2[5] and v2[5] ~= "" then dropRate = v2[5] lastDropRate = dropRate else lastDropRate = nil end break end end end end -- check if its a dungeon/raid loot if not isCraft and not isWBLoot and not isPvP and not isRepReward and not isWorldEvent and not isSetPiece then for k1,v1 in pairs(AtlasLoot_Data["AtlasLootItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootItems"][k1]) do if v2[1] == itemID then if k1 ~= "VanillaKeys" then source = k1 end if v2[5] and v2[5] ~= "" then dropRate = v2[5] lastDropRate = dropRate else lastDropRate = nil end break end end end -- check containers for k1,v1 in pairs(AtlasLoot_Data["AtlasLootItems"]) do if source then break end for k2,v2 in pairs(AtlasLoot_Data["AtlasLootItems"][k1]) do if source then break end if v2[16] then for i, n in pairs(v2[16]) do if source then break end for i2, n2 in pairs(v2[16][i]) do if v2[16][i][i2][1] == itemID then source = k1 break end end end end end end end lastItemID = itemID if not source then lastSourceStr = nil return end for k,v in pairs(AtlasLoot_TableNames) do if k == source then sourceStr = AtlasLoot_TableNames[k][1] lastSourceStr = sourceStr break end end if not sourceStr then return end -- if line2:GetText() then local str if dropRate then str = GREY..sourceStr.." ("..dropRate..")|r" else str = GREY..sourceStr.."|r" end AddSourceLine(tooltip, str) -- end elseif lastSourceStr then -- if line2:GetText() then local str if lastDropRate then str = GREY..lastSourceStr.." ("..lastDropRate..")|r" else str = GREY..lastSourceStr.."|r" end AddSourceLine(tooltip, str) -- end end end end local lastSearchName local lastSearchID local function GetItemIDByName(name) if not name then return nil end if name ~= lastSearchName then for itemID = 1, 99999 do local itemName = GetItemInfo(itemID) if (itemName and itemName == name) then lastSearchID = itemID break end end lastSearchName = name end return lastSearchID end local function HookTooltip(tooltip) local original_SetLootRollItem = tooltip.SetLootRollItem local original_SetLootItem = tooltip.SetLootItem local original_SetMerchantItem = tooltip.SetMerchantItem local original_SetQuestLogItem = tooltip.SetQuestLogItem local original_SetQuestItem = tooltip.SetQuestItem local original_SetHyperlink = tooltip.SetHyperlink local original_SetBagItem = tooltip.SetBagItem local original_SetInboxItem = tooltip.SetInboxItem local original_SetInventoryItem = tooltip.SetInventoryItem local original_SetCraftItem = tooltip.SetCraftItem local original_SetCraftSpell = tooltip.SetCraftSpell local original_SetTradeSkillItem = tooltip.SetTradeSkillItem local original_SetAuctionItem = tooltip.SetAuctionItem local original_SetAuctionSellItem = tooltip.SetAuctionSellItem local original_SetTradePlayerItem = tooltip.SetTradePlayerItem local original_SetTradeTargetItem = tooltip.SetTradeTargetItem local original_OnHide = tooltip:GetScript("OnHide") tooltip:SetScript("OnHide", function() if original_OnHide then original_OnHide() end this.itemID = nil end) function tooltip.SetLootRollItem(self, rollID) original_SetLootRollItem(self, rollID) local _, _, id = strfind(GetLootRollItemLink(rollID) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetLootItem(self, slot) original_SetLootItem(self, slot) local _, _, id = strfind(GetLootSlotLink(slot) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetMerchantItem(self, merchantIndex) original_SetMerchantItem(self, merchantIndex) local _, _, id = strfind(GetMerchantItemLink(merchantIndex) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetQuestLogItem(self, itemType, index) original_SetQuestLogItem(self, itemType, index) local _, _, id = strfind(GetQuestLogItemLink(itemType, index) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetQuestItem(self, itemType, index) original_SetQuestItem(self, itemType, index) local _, _, id = strfind(GetQuestItemLink(itemType, index) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetHyperlink(self, arg1) original_SetHyperlink(self, arg1) local _, _, id = strfind(arg1 or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetBagItem(self, container, slot) local hasCooldown, repairCost = original_SetBagItem(self, container, slot) local _, _, id = strfind(GetContainerItemLink(container, slot) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) return hasCooldown, repairCost end function tooltip.SetInboxItem(self, mailID, attachmentIndex) original_SetInboxItem(self, mailID, attachmentIndex) local itemName = GetInboxItem(mailID) self.itemID = GetItemIDByName(itemName) ExtendTooltip(self) end function tooltip.SetInventoryItem(self, unit, slot) local hasItem, hasCooldown, repairCost = original_SetInventoryItem(self, unit, slot) local _, _, id = strfind(GetInventoryItemLink(unit, slot) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) return hasItem, hasCooldown, repairCost end function tooltip.SetCraftItem(self, skill, slot) original_SetCraftItem(self, skill, slot) local _, _, id = strfind(GetCraftReagentItemLink(skill, slot) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetCraftSpell(self, slot) original_SetCraftSpell(self, slot) local _, _, id = strfind(GetCraftItemLink(slot) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetTradeSkillItem(self, skillIndex, reagentIndex) original_SetTradeSkillItem(self, skillIndex, reagentIndex) if reagentIndex then local _, _, id = strfind(GetTradeSkillReagentItemLink(skillIndex, reagentIndex) or "", "item:(%d+)") self.itemID = tonumber(id) else local _, _, id = strfind(GetTradeSkillItemLink(skillIndex) or "", "item:(%d+)") self.itemID = tonumber(id) end ExtendTooltip(self) end function tooltip.SetAuctionItem(self, atype, index) original_SetAuctionItem(self, atype, index) local itemName = GetAuctionItemInfo(atype, index) self.itemID = GetItemIDByName(itemName) ExtendTooltip(self) end function tooltip.SetAuctionSellItem(self) original_SetAuctionSellItem(self) local itemName = GetAuctionSellItemInfo() self.itemID = GetItemIDByName(itemName) ExtendTooltip(self) end function tooltip.SetTradePlayerItem(self, index) original_SetTradePlayerItem(self, index) local _, _, id = strfind(GetTradePlayerItemLink(index) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end function tooltip.SetTradeTargetItem(self, index) original_SetTradeTargetItem(self, index) local _, _, id = strfind(GetTradeTargetItemLink(index) or "", "item:(%d+)") self.itemID = tonumber(id) ExtendTooltip(self) end end HookTooltip(GameTooltip) HookTooltip(ItemRefTooltip) AtlasLootTip:SetScript("OnShow", function() if aux_frame and aux_frame:IsVisible() then if GetMouseFocus():GetParent() then if GetMouseFocus():GetParent().row then if GetMouseFocus():GetParent().row.record.item_id then GameTooltip.itemID = GetMouseFocus():GetParent().row.record.item_id end end end ExtendTooltip(GameTooltip) end end) -- adapted from http://shagu.org/ShaguTweaks/ AtlasLootTip.HookAddonOrVariable = function(addon, func) local lurker = CreateFrame("Frame", nil) lurker.func = func lurker:RegisterEvent("ADDON_LOADED") lurker:RegisterEvent("VARIABLES_LOADED") lurker:RegisterEvent("PLAYER_ENTERING_WORLD") lurker:SetScript("OnEvent",function() if IsAddOnLoaded(addon) or getglobal(addon) then this:func() this:UnregisterAllEvents() end end) end AtlasLootTip.HookAddonOrVariable("Tmog", function() HookTooltip(TmogTooltip) end)