-- Store local copies of the original quest log functions |
local origGetNumQuestLogEntries = GetNumQuestLogEntries |
local origGetQuestLogTitle = GetQuestLogTitle |
local origSelectQuestLogEntry = SelectQuestLogEntry |
local origGetQuestLogSelection = GetQuestLogSelection |
local origGetQuestLink = GetQuestLink |
local origIsQuestWatched = IsQuestWatched |
local origRemoveQuestWatch = RemoveQuestWatch |
local origAddQuestWatch = AddQuestWatch |
local origGetNumQuestLeaderBoards = GetNumQuestLeaderBoards |
local origGetQuestIndexForWatch = GetQuestIndexForWatch |
local origGetQuestLogLeaderBoard = GetQuestLogLeaderBoard |
local origGetQuestLogSpecialItemInfo = GetQuestLogSpecialItemInfo |
local origGetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemCooldown |
|
local hooksActive = false |
local activeFilter = "ALL" |
|
-- These filter functions take in the returns from GetQuestLogTitle as well |
-- as an additional parameter called headerName, which is the title of the |
-- header that the quest entry occurs underneath in the full quest log. |
local filters = { |
["DAILY"] = function(...) return (select(8, ...)) end, |
["GROUP"] = function(title, level, tag) return tag == "Group" end, |
["COMPLETE"] = function(...) return (select(7, ...)) end, |
["DUNGEON"] = function(title, level, tag) return tag == "Dungeon" end, |
["ELITE"] = function(title, level, tag) return tag == "Elite" end, |
["HEROIC"] = function(title, level, tag) return tag == "Heroic" end, |
["PVP"] = function(title, level, tag) return tag == "PvP" end, |
["RAID"] = function(title, level, tag) return tag == "Raid" end, |
["My Zone"] = function(...) return select(9, ...) == GetRealZoneText() end, |
["Test"] = function() return true end, |
} |
|
-- This function does the transformation from indices in the normal quest log |
-- to those in the "filtered" quest log. In addition this function provides |
-- the functionality of GetNumQuestLogEntries() when the index parameter |
-- is nil. |
local function filterQuests(index, filterName) |
local numEntries, numQuests = origGetNumQuestLogEntries() |
local scannedQuests = 0 |
local filteredEntries = 0 |
local counter = 1 |
local headerName |
|
while scannedQuests < numQuests do |
local title, level, tag, group, header, collapsed, complete, daily = origGetQuestLogTitle(counter) |
if header then |
headerName = title |
else |
if counter > numEntries then |
headerName = nil |
end |
local filterFunc = filters[filterName] |
if filterFunc(title, level, tag, group, header, collapsed, complete, daily, headerName) then |
filteredEntries = filteredEntries + 1 |
end |
if filteredEntries == index then |
return counter |
end |
scannedQuests = scannedQuests + 1 |
end |
counter = counter + 1 |
end |
|
if not index then |
return filteredEntries, scannedQuests |
end |
end |
|
-- Simple factory function that makes hook functions. This is only meant to |
-- be used when the function being hooked expects the quest index as the |
-- first argument, and the returns do not need to be altered. |
local function makeHookFunction(origFunc) |
return function(index, ...) |
if not hooksActive then |
return origFunc(index, ...) |
else |
local newIndex = filterQuests(index, activeFilter) |
return origFunc(newIndex, ...) |
end |
end |
end |
|
-- Hook the easy functions |
GetQuestLogTitle = makeHookFunction(origGetQuestLogTitle) |
SelectQuestLogEntry = makeHookFunction(origSelectQuestLogEntry) |
GetQuestLink = makeHookFunction(origGetQuestLink) |
IsQuestWatched = makeHookFunction(origIsQuestWatched) |
AddQuestWatch = makeHookFunction(origAddQuestWatch) |
RemoveQuestWatch = makeHookFunction(origRemoveQuestWatch) |
GetNumQuestLeaderBoards = makeHookFunction(origGetNumQuestLeaderBoards) |
--GetQuestLogSpecialItemInfo = makeHookFunction(origGetQuestLogSpecialItemInfo) |
--GetQuestLogSpecialItemCooldown = makeHookFunction(origGetQuestLogSpecialItemCooldown) |
|
function GetNumQuestLogEntries(...) |
if not hooksActive then |
return origGetNumQuestLogEntries(...) |
else |
return filterQuests(nil, activeFilter) |
end |
end |
|
-- This function does the reverse of filterQuests, converting the value from |
-- the actual GetQuestLogSelection function to the "filtered" quest log |
-- index. |
function GetQuestLogSelection(...) |
if not hooksActive then |
return origGetQuestLogSelection(...) |
else |
local selected = origGetQuestLogSelection() |
for i=1,selected do |
local newIndex = filterQuests(i, activeFilter) |
if newIndex == selected then |
return i |
end |
end |
return 0 |
end |
end |
|
function GetQuestIndexForWatch(...) |
if not hooksActive then |
return origGetQuestIndexForWatch(...) |
else |
local index = origGetQuestIndexForWatch(...) |
for i=1,index do |
local newIndex = filterQuests(i, activeFilter) |
if newIndex == index then |
return i |
end |
end |
end |
end |
|
function GetQuestLogLeaderBoard(objId, questId, ...) |
if not hooksActive then |
return origGetQuestLogLeaderBoard(objId, questId, ...) |
else |
local newIndex = filterQuests(questId, activeFilter) |
return origGetQuestLogLeaderBoard(objId, newIndex, ...) |
end |
end |
|
local tabs = {} |
local function createTabFrame(name) |
local tab = CreateFrame("Button", name, QuestLogFrame, "CharacterFrameTabButtonTemplate") |
tab:SetScript("OnClick", function(self, button) |
PanelTemplates_Tab_OnClick(self, QuestLogFrame); |
QuestTabs_OnClick(self, button); |
end) |
table.insert(tabs, tab) |
return tab |
end |
|
function QuestTabs_Update() |
local numEntries, numQuests = origGetNumQuestLogEntries() |
local counter = 1 |
local scannedQuests = 0 |
local availFilters = {} |
local headerName |
|
while scannedQuests < numQuests do |
local title, level, tag, group, header, collapsed, complete, daily = origGetQuestLogTitle(counter) |
if header then |
headerName = title |
end |
if counter > numEntries then |
headerName = nil |
end |
if not header then |
scannedQuests = scannedQuests + 1 |
end |
for name,filterFunc in pairs(filters) do |
if filterFunc(title, level, tag, group, header, collapsed, complete, daily, headerName) then |
availFilters[name] = true |
end |
end |
counter = counter + 1 |
end |
|
local tabList = {"ALL"} |
for k,v in pairs(availFilters) do |
table.insert(tabList, k) |
end |
|
table.sort(tabList) |
|
for i=1,#tabList do |
local name = "QuestLogFrameTab" .. i |
local tab = getglobal(name) |
if not tab then |
tab = createTabFrame(name) |
tab:SetID(i) |
|
if i == 1 then |
tab:ClearAllPoints() |
tab:SetPoint("BOTTOMLEFT", 11, 20) |
else |
local prevName = "QuestLogFrameTab" .. i - 1 |
local prevTab = getglobal(prevName) |
tab:ClearAllPoints() |
tab:SetPoint("LEFT", prevTab, "RIGHT", -15, 0) |
end |
end |
|
tab:SetText(getglobal(tabList[i]) or tabList[i]) |
PanelTemplates_TabResize(tab, 0); |
tab.filter = tabList[i] |
end |
|
for i=#tabList + 1,#tabs do |
tabs[i]:Hide() |
end |
|
QuestLogFrame.numTabs = #tabList |
PanelTemplates_UpdateTabs(QuestLogFrame) |
end |
|
local eventFrame = CreateFrame("Frame") |
eventFrame:RegisterEvent("QUEST_LOG_UPDATE") |
eventFrame:RegisterEvent("ZONE_CHANGED") |
eventFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA") |
eventFrame:SetScript("OnEvent", function(self, event, ...) |
QuestTabs_Update() |
if QuestLogFrame:IsVisible() then |
QuestLog_Update() |
end |
end) |
|
function QuestTabs_OnClick(self, button) |
if self.filter == "ALL" then |
hooksActive = false |
QuestLog_Update() |
else |
hooksActive = true |
activeFilter = self.filter |
QuestLog_Update() |
end |
end |
|
QuestTabs_Update() |
QuestLogFrameTab1:Click() |