You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
568 lines
18 KiB
568 lines
18 KiB
-- ----------------------------------------------------------------------------
|
|
-- Localized globals.
|
|
-- ----------------------------------------------------------------------------
|
|
-- Lua Functions
|
|
local pairs = _G.pairs
|
|
|
|
-- Lua Libraries
|
|
local table = _G.table
|
|
|
|
-- WoW UI
|
|
local C_PetJournal = _G.C_PetJournal
|
|
local C_ToyBox = _G.C_ToyBox
|
|
local GameTooltip = _G.GameTooltip
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- AddOn namespace.
|
|
-- ----------------------------------------------------------------------------
|
|
local AddOnFolderName, private = ...
|
|
local Data = private.Data
|
|
local EventMessage = private.EventMessage
|
|
|
|
local LibStub = _G.LibStub
|
|
local LibQTip = LibStub("LibQTip-1.0")
|
|
local NPCScan = LibStub("AceAddon-3.0"):GetAddon(AddOnFolderName)
|
|
|
|
local FormatAtlasTexture = private.FormatAtlasTexture
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- Constants
|
|
-- ----------------------------------------------------------------------------
|
|
local DataObject = LibStub("LibDataBroker-1.1"):NewDataObject(
|
|
AddOnFolderName,
|
|
{
|
|
icon = [[Interface\LFGFRAME\BattlenetWorking0]],
|
|
label = _G.OBJECTIVES_LABEL,
|
|
scannerData = {
|
|
NPCCount = 0,
|
|
NPCs = {},
|
|
},
|
|
text = _G.NONE,
|
|
type = "data source"
|
|
}
|
|
)
|
|
|
|
local npcAchievementNames = {}
|
|
local npcDisplayNames = {}
|
|
local npcIDs = {}
|
|
local npcNames = {}
|
|
|
|
local TitleFont = _G.CreateFont("NPCScanTitleFont")
|
|
TitleFont:SetTextColor(1, 0.82, 0)
|
|
TitleFont:SetFontObject("QuestTitleFont")
|
|
|
|
local Tooltip
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- Helpers
|
|
-- ----------------------------------------------------------------------------
|
|
local function SortByNPCNameThenByID(a, b)
|
|
local nameA = npcNames[a]
|
|
local nameB = npcNames[b]
|
|
|
|
if nameA == nameB then
|
|
return a < b
|
|
end
|
|
|
|
return nameA < nameB
|
|
end
|
|
|
|
local function SortByNPCAchievementNameThenByNameThenByID(a, b)
|
|
local achievementNameA = npcAchievementNames[a]
|
|
local achievementNameB = npcAchievementNames[b]
|
|
|
|
if achievementNameA == achievementNameB then
|
|
return SortByNPCNameThenByID(a, b)
|
|
end
|
|
|
|
if not achievementNameA then
|
|
return false
|
|
end
|
|
|
|
if not achievementNameB then
|
|
return true
|
|
end
|
|
|
|
return achievementNameA < achievementNameB
|
|
end
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- Tooltip achievement headers.
|
|
-- ----------------------------------------------------------------------------
|
|
local achievementProvider, achievementPrototype, baseCellPrototype = LibQTip:CreateCellProvider(LibQTip.LabelProvider)
|
|
|
|
function achievementPrototype:getContentHeight()
|
|
return 16
|
|
end
|
|
|
|
function achievementPrototype:InitializeCell()
|
|
baseCellPrototype.InitializeCell(self)
|
|
|
|
if not self.atlas then
|
|
local background = self:CreateTexture(nil, "TOOLTIP")
|
|
background:SetBlendMode("ADD")
|
|
background:SetAtlas("Objective-Header", true)
|
|
background:SetPoint("CENTER", 0, -17)
|
|
|
|
self.atlas = background
|
|
end
|
|
|
|
self.r, self.g, self.b = 1, 0.82, 0
|
|
self.fontString:SetTextColor(self.r, self.g, self.b, 1)
|
|
end
|
|
|
|
function achievementPrototype:ReleaseCell()
|
|
self.r, self.g, self.b = 1, 1, 1
|
|
end
|
|
|
|
function achievementPrototype:SetupCell(tooltip, value, justification, font, r, g, b)
|
|
local width, height = baseCellPrototype.SetupCell(self, tooltip, value, justification, font, r, g, b)
|
|
|
|
self.r, self.g, self.b = 1, 0.82, 0
|
|
|
|
return width, height
|
|
end
|
|
|
|
local function OpenToAchievement(_, achievementID)
|
|
if not _G.AchievementFrame or not _G.AchievementFrame:IsShown() then
|
|
_G.ToggleAchievementFrame()
|
|
end
|
|
|
|
_G.AchievementFrameBaseTab_OnClick(1)
|
|
_G.AchievementFrame_SelectAchievement(achievementID)
|
|
|
|
local categoryID = _G.GetAchievementCategory(achievementID)
|
|
local _, parentCategoryID = _G.GetCategoryInfo(categoryID)
|
|
|
|
if parentCategoryID == -1 then
|
|
for _, entry in pairs(_G.ACHIEVEMENTUI_CATEGORIES) do
|
|
if entry.id == categoryID then
|
|
entry.collapsed = false
|
|
elseif entry.parent == categoryID then
|
|
entry.hidden = false
|
|
end
|
|
end
|
|
|
|
_G.AchievementFrameCategories_Update()
|
|
end
|
|
end
|
|
|
|
local function ShowAchievementTooltip(tooltipCell, achievementID)
|
|
Tooltip:SetFrameStrata("DIALOG")
|
|
_G.GameTooltip_SetDefaultAnchor(GameTooltip, tooltipCell)
|
|
|
|
GameTooltip:SetText(Data.Achievements[achievementID].description, 1, 1, 1, 1, true)
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
local function HideAchievementTooltip()
|
|
Tooltip:SetFrameStrata("TOOLTIP")
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- NPC tidbit helpers
|
|
-- ----------------------------------------------------------------------------
|
|
local entryFromID = {}
|
|
|
|
local function Tooltip_OnRelease()
|
|
Tooltip = nil
|
|
end
|
|
|
|
local DataTooltip
|
|
|
|
local function DataTooltip_OnRelease()
|
|
DataTooltip = nil
|
|
|
|
if Tooltip then
|
|
Tooltip:SetFrameStrata("TOOLTIP")
|
|
end
|
|
end
|
|
|
|
local function AddEntryDataIDs(list, fieldName)
|
|
table.wipe(entryFromID)
|
|
|
|
for index = 1, #list do
|
|
entryFromID[list[index][fieldName]] = list[index]
|
|
end
|
|
end
|
|
|
|
local function AddEntryToDataTooltip(iconPath, entryName, isCollected)
|
|
local line = DataTooltip:AddLine(("|T%s:0:0|t %s"):format(iconPath, entryName))
|
|
|
|
if isCollected then
|
|
DataTooltip:SetCell(line, 2, ("%s%s"):format(_G.GREEN_FONT_COLOR_CODE, _G.COLLECTED))
|
|
else
|
|
DataTooltip:SetCell(line, 2, ("%s%s"):format(_G.RED_FONT_COLOR_CODE, _G.NOT_COLLECTED))
|
|
end
|
|
end
|
|
|
|
local function CleanupDataTooltip()
|
|
if DataTooltip then
|
|
DataTooltip:Hide()
|
|
DataTooltip:Release()
|
|
end
|
|
|
|
if Tooltip then
|
|
Tooltip:SetFrameStrata("TOOLTIP")
|
|
end
|
|
end
|
|
|
|
local function InitializeDataTooltip(tooltipCell)
|
|
if not DataTooltip then
|
|
DataTooltip = LibQTip:Acquire(AddOnFolderName .. "DataTooltip", 2)
|
|
DataTooltip:SetAutoHideDelay(0.1, tooltipCell, DataTooltip_OnRelease)
|
|
DataTooltip:SmartAnchorTo(tooltipCell)
|
|
DataTooltip:SetBackdropColor(0.05, 0.05, 0.05, 1)
|
|
DataTooltip:SetCellMarginH(0)
|
|
end
|
|
|
|
Tooltip:SetFrameStrata("DIALOG")
|
|
DataTooltip:Clear()
|
|
|
|
return DataTooltip
|
|
end
|
|
|
|
local function DisplayText(tooltipCell, text)
|
|
InitializeDataTooltip(tooltipCell)
|
|
DataTooltip:AddLine(text)
|
|
DataTooltip:Show()
|
|
end
|
|
|
|
local function DisplayMountInfo(tooltipCell, mountList)
|
|
AddEntryDataIDs(mountList, "spellID")
|
|
InitializeDataTooltip(tooltipCell)
|
|
|
|
local mountIDs = _G.C_MountJournal.GetMountIDs()
|
|
|
|
for index = 1, #mountIDs do
|
|
local creatureName, spellID, iconPath, _, _, _, _, _, _, hideOnChar, isCollected = _G.C_MountJournal.GetMountInfoByID(mountIDs[index])
|
|
|
|
if creatureName and not hideOnChar and entryFromID[spellID] then
|
|
AddEntryToDataTooltip(iconPath, creatureName, isCollected)
|
|
end
|
|
end
|
|
|
|
DataTooltip:UpdateScrolling()
|
|
DataTooltip:Show()
|
|
end
|
|
|
|
local function DisplayPetInfo(tooltipCell, petList)
|
|
AddEntryDataIDs(petList, "npcID")
|
|
InitializeDataTooltip(tooltipCell)
|
|
|
|
C_PetJournal.SetFilterChecked(_G.LE_PET_JOURNAL_FILTER_COLLECTED, true)
|
|
C_PetJournal.SetFilterChecked(_G.LE_PET_JOURNAL_FILTER_FAVORITES, false)
|
|
C_PetJournal.SetFilterChecked(_G.LE_PET_JOURNAL_FILTER_NOT_COLLECTED, true)
|
|
C_PetJournal.SetAllPetTypesChecked(true)
|
|
C_PetJournal.SetAllPetSourcesChecked(true)
|
|
C_PetJournal.ClearSearchFilter()
|
|
|
|
if _G.PetJournalSearchBox then
|
|
_G.PetJournalSearchBox:SetText("");
|
|
end
|
|
|
|
local numPets = C_PetJournal.GetNumPets()
|
|
|
|
for index = 1, numPets do
|
|
local _, _, isCollected, _, _, _, _, petName, iconPath, _, npcID = C_PetJournal.GetPetInfoByIndex(index)
|
|
|
|
if petName and entryFromID[npcID] then
|
|
AddEntryToDataTooltip(iconPath, petName, isCollected)
|
|
entryFromID[npcID] = nil -- Prevent multiples if already collected.
|
|
end
|
|
end
|
|
|
|
DataTooltip:UpdateScrolling()
|
|
DataTooltip:Show()
|
|
end
|
|
|
|
local function DisplayToyInfo(tooltipCell, toyList)
|
|
AddEntryDataIDs(toyList, "itemID")
|
|
InitializeDataTooltip(tooltipCell)
|
|
|
|
C_ToyBox.SetAllSourceTypeFilters(true)
|
|
C_ToyBox.SetCollectedShown(true)
|
|
C_ToyBox.SetFilterString("")
|
|
|
|
if _G.ToyBox then
|
|
_G.ToyBox.searchBox:SetText("");
|
|
end
|
|
|
|
local numToys = C_ToyBox.GetNumToys()
|
|
|
|
for index = 1, numToys do
|
|
local toyID = C_ToyBox.GetToyFromIndex(index)
|
|
local itemID, toyName, iconPath = C_ToyBox.GetToyInfo(toyID)
|
|
|
|
if toyName and entryFromID[itemID] then
|
|
AddEntryToDataTooltip(iconPath, toyName, _G.PlayerHasToy(itemID))
|
|
end
|
|
end
|
|
|
|
DataTooltip:UpdateScrolling()
|
|
DataTooltip:Show()
|
|
end
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- DataBroker Tooltip helpers.
|
|
-- ----------------------------------------------------------------------------
|
|
local function GetTooltipData()
|
|
local hasMounts = false
|
|
local hasPets = false
|
|
local hasToys = false
|
|
local hasTameable = false
|
|
local hasWorldQuest = false
|
|
|
|
local mountsColumn
|
|
local petsColumn
|
|
local tameableColumn
|
|
local toysColumn
|
|
local worldQuestColumn
|
|
|
|
local numTooltipColumns = 1
|
|
|
|
table.wipe(npcAchievementNames)
|
|
table.wipe(npcDisplayNames)
|
|
table.wipe(npcIDs)
|
|
table.wipe(npcNames)
|
|
|
|
|
|
for npcID in pairs(DataObject.scannerData.NPCs) do
|
|
local npc = Data.NPCs[npcID]
|
|
|
|
-- The npcID may belong to a custom NPC, which will not have further information.
|
|
if npc then
|
|
npcAchievementNames[npcID] = npc.achievementID and Data.Achievements[npc.achievementID].name or nil
|
|
npcDisplayNames[npcID] = private.GetNPCOptionsName(npcID)
|
|
npcIDs[#npcIDs + 1] = npcID
|
|
npcNames[npcID] = NPCScan:GetNPCNameFromID(npcID)
|
|
|
|
if not hasTameable and npc.isTameable then
|
|
hasTameable = true
|
|
end
|
|
|
|
if not hasMounts and npc.mounts then
|
|
hasMounts = true
|
|
end
|
|
|
|
if not hasPets and npc.pets then
|
|
hasPets = true
|
|
end
|
|
|
|
if not hasToys and npc.toys then
|
|
hasToys = true
|
|
end
|
|
|
|
if not hasWorldQuest and npc:HasActiveWorldQuest() then
|
|
hasWorldQuest = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if hasMounts then
|
|
numTooltipColumns = numTooltipColumns + 1
|
|
mountsColumn = numTooltipColumns
|
|
end
|
|
|
|
if hasPets then
|
|
numTooltipColumns = numTooltipColumns + 1
|
|
petsColumn = numTooltipColumns
|
|
end
|
|
|
|
if hasToys then
|
|
numTooltipColumns = numTooltipColumns + 1
|
|
toysColumn = numTooltipColumns
|
|
end
|
|
|
|
if hasTameable then
|
|
numTooltipColumns = numTooltipColumns + 1
|
|
tameableColumn = numTooltipColumns
|
|
end
|
|
|
|
if hasWorldQuest then
|
|
numTooltipColumns = numTooltipColumns + 1
|
|
worldQuestColumn = numTooltipColumns
|
|
end
|
|
|
|
table.sort(npcIDs, SortByNPCAchievementNameThenByNameThenByID)
|
|
|
|
return {
|
|
mountsColumn = mountsColumn,
|
|
petsColumn = petsColumn,
|
|
tameableColumn = tameableColumn,
|
|
toysColumn = toysColumn,
|
|
worldQuestColumn = worldQuestColumn,
|
|
numTooltipColumns = numTooltipColumns
|
|
}
|
|
end
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- DataBroker Tooltip.
|
|
-- ----------------------------------------------------------------------------
|
|
local ICON_MOUNT = FormatAtlasTexture("StableMaster")
|
|
local ICON_PET = FormatAtlasTexture("WildBattlePetCapturable")
|
|
|
|
local ICON_TAMEABLE
|
|
do
|
|
local textureFormat = [[|TInterface\TargetingFrame\UI-CLASSES-CIRCLES:0:0:0:0:256:256:%d:%d:%d:%d|t]]
|
|
local textureSize = 256
|
|
local left, right, top, bottom = _G.unpack(_G.CLASS_ICON_TCOORDS["HUNTER"])
|
|
|
|
ICON_TAMEABLE = textureFormat:format(left * textureSize, right * textureSize, top * textureSize, bottom * textureSize)
|
|
end
|
|
|
|
local ICON_TOY = [[|TInterface\Worldmap\TreasureChest_64:0:0|t]]
|
|
local ICON_WORLDQUEST = FormatAtlasTexture("worldquest-tracker-questmarker")
|
|
|
|
local DataObjectDisplay -- Used for updates.
|
|
|
|
local function DrawTooltip(displayFrame)
|
|
if not displayFrame then
|
|
return
|
|
end
|
|
|
|
DataObjectDisplay = displayFrame
|
|
|
|
if LibQTip:IsAcquired(AddOnFolderName) then
|
|
LibQTip:Release(AddOnFolderName)
|
|
end
|
|
|
|
local tooltipData = GetTooltipData()
|
|
|
|
Tooltip = LibQTip:Acquire(AddOnFolderName, tooltipData.numTooltipColumns)
|
|
Tooltip:SmartAnchorTo(displayFrame)
|
|
Tooltip:SetAutoHideDelay(0.25, displayFrame)
|
|
Tooltip:Clear()
|
|
Tooltip:SetBackdropColor(0.05, 0.05, 0.05, 1)
|
|
Tooltip:SetCellMarginH(0)
|
|
Tooltip:SetCellMarginV(1)
|
|
|
|
Tooltip.OnRelease = Tooltip_OnRelease
|
|
|
|
|
|
Tooltip:SetCell(Tooltip:AddLine(), 1, AddOnFolderName, TitleFont, "CENTER", 0)
|
|
Tooltip:AddSeparator(1, 0, 0, 0)
|
|
|
|
if DataObject.scannerData.NPCCount == 0 then
|
|
Tooltip:AddSeparator(1, 0, 0, 0)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
Tooltip:SetCell(Tooltip:AddLine(), 1, _G.ERR_GENERIC_NO_VALID_TARGETS, "CENTER", 0)
|
|
|
|
return
|
|
end
|
|
|
|
local mountsColumn = tooltipData.mountsColumn
|
|
local petsColumn = tooltipData.petsColumn
|
|
local tameableColumn = tooltipData.tameableColumn
|
|
local toysColumn = tooltipData.toysColumn
|
|
local worldQuestColumn = tooltipData.worldQuestColumn
|
|
|
|
local currentAchievementID
|
|
|
|
for index = 1, #npcIDs do
|
|
local npcID = npcIDs[index]
|
|
local npc = Data.NPCs[npcID]
|
|
|
|
if npc.achievementID then
|
|
if npc.achievementID ~= currentAchievementID then
|
|
currentAchievementID = npc.achievementID
|
|
|
|
Tooltip:AddSeparator(1, 0, 0, 0)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
|
|
local achievementData = Data.Achievements[npc.achievementID]
|
|
local achievementLine = Tooltip:AddLine()
|
|
|
|
Tooltip:SetCell(achievementLine, 1, ("|T%s:0|t %s"):format(achievementData.iconTexturePath, achievementData.name), "CENTER", 0, achievementProvider)
|
|
Tooltip:SetLineScript(achievementLine, "OnMouseUp", OpenToAchievement, npc.achievementID)
|
|
Tooltip:SetLineScript(achievementLine, "OnEnter", ShowAchievementTooltip, npc.achievementID)
|
|
Tooltip:SetLineScript(achievementLine, "OnLeave", HideAchievementTooltip)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
end
|
|
elseif not currentAchievementID then
|
|
-- No achievement section before this, and it's the first entry
|
|
currentAchievementID = -1
|
|
|
|
Tooltip:AddSeparator(1, 0, 0, 0)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
elseif currentAchievementID >= 0 then
|
|
-- End of achievements.
|
|
currentAchievementID = -1
|
|
|
|
Tooltip:AddSeparator(1, 0, 0, 0)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
Tooltip:SetCell(Tooltip:AddLine(), 1, _G.MISCELLANEOUS, "CENTER", 0)
|
|
Tooltip:AddSeparator(1, 1, 0.82, 0)
|
|
end
|
|
|
|
local line = Tooltip:AddLine()
|
|
|
|
if line % 2 == 0 then
|
|
Tooltip:SetLineColor(line, 0.20, 0.20, 0.20)
|
|
end
|
|
|
|
Tooltip:SetCell(line, 1, npcDisplayNames[npcID])
|
|
|
|
if worldQuestColumn and npc:HasActiveWorldQuest() then
|
|
Tooltip:SetCell(line, worldQuestColumn, ICON_WORLDQUEST)
|
|
Tooltip:SetCellScript(line, worldQuestColumn, "OnEnter", DisplayText, _G.TRACKER_HEADER_WORLD_QUESTS)
|
|
Tooltip:SetCellScript(line, worldQuestColumn, "OnLeave", CleanupDataTooltip)
|
|
end
|
|
|
|
if tameableColumn and npc.isTameable then
|
|
Tooltip:SetCell(line, tameableColumn, ICON_TAMEABLE)
|
|
Tooltip:SetCellScript(line, tameableColumn, "OnEnter", DisplayText, _G.TAMEABLE)
|
|
Tooltip:SetCellScript(line, tameableColumn, "OnLeave", CleanupDataTooltip)
|
|
end
|
|
|
|
if mountsColumn and npc.mounts then
|
|
Tooltip:SetCell(line, mountsColumn, ICON_MOUNT)
|
|
Tooltip:SetCellScript(line, mountsColumn, "OnEnter", DisplayMountInfo, npc.mounts)
|
|
Tooltip:SetCellScript(line, mountsColumn, "OnLeave", CleanupDataTooltip)
|
|
end
|
|
|
|
if petsColumn and npc.pets then
|
|
Tooltip:SetCell(line, petsColumn, ICON_PET)
|
|
Tooltip:SetCellScript(line, petsColumn, "OnEnter", DisplayPetInfo, npc.pets)
|
|
Tooltip:SetCellScript(line, petsColumn, "OnLeave", CleanupDataTooltip)
|
|
end
|
|
|
|
if toysColumn and npc.toys then
|
|
Tooltip:SetCell(line, toysColumn, ICON_TOY)
|
|
Tooltip:SetCellScript(line, toysColumn, "OnEnter", DisplayToyInfo, npc.toys)
|
|
Tooltip:SetCellScript(line, toysColumn, "OnLeave", CleanupDataTooltip)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- DataObject methods.
|
|
-- ----------------------------------------------------------------------------
|
|
function DataObject:OnClick()
|
|
LibStub("AceConfigDialog-3.0"):Open(AddOnFolderName)
|
|
end
|
|
|
|
function DataObject:OnEnter()
|
|
if not Tooltip or not Tooltip:IsShown() then
|
|
DrawTooltip(self)
|
|
Tooltip:UpdateScrolling()
|
|
Tooltip:Show()
|
|
end
|
|
end
|
|
|
|
function DataObject:OnLeave()
|
|
-- Null operation: Some LDB displays get cranky if this method is missing.
|
|
end
|
|
|
|
function DataObject:Update(_, scannerData)
|
|
self.text = scannerData.NPCCount > 0 and scannerData.NPCCount or _G.NONE
|
|
self.scannerData = scannerData
|
|
|
|
if DataObjectDisplay and Tooltip and Tooltip:IsShown() then
|
|
DrawTooltip(DataObjectDisplay)
|
|
end
|
|
end
|
|
|
|
LibStub("AceEvent-3.0"):Embed(DataObject)
|
|
DataObject:RegisterMessage(EventMessage.ScannerDataUpdated, "Update")
|
|
|