diff --git a/api/hunterbook-tab-beastlore.lua b/api/hunterbook-tab-beastlore.lua
index 4a2fb89..b682392 100644
--- a/api/hunterbook-tab-beastlore.lua
+++ b/api/hunterbook-tab-beastlore.lua
@@ -24,6 +24,33 @@ function MTH_BOOK_GetBeastAbilitiesSummary(beast)
return tostring(beast.abilities)
end
+-- Like the summary, but colours each ability green when the hunter already knows
+-- that exact rank and red when it is still unlearned, to spot tameable upgrades.
+function MTH_BOOK_GetBeastAbilitiesColored(beast)
+ if not beast or not beast.abilities or beast.abilities == "" or beast.abilities == "None" then
+ return "-"
+ end
+ local tokens = MTH_BOOK_SplitAbilities(beast.abilities)
+ if table.getn(tokens) == 0 then
+ return "-"
+ end
+ local canCheck = type(MTH_IsPetAbilityKnownByHunter) == "function"
+ local parts = {}
+ for i = 1, table.getn(tokens) do
+ local text = tostring(tokens[i])
+ if canCheck then
+ local _, label, rank = MTH_BOOK_ParseAbilityToken(tokens[i])
+ if MTH_IsPetAbilityKnownByHunter(label, rank) then
+ text = "|cff40ff40" .. text .. "|r"
+ else
+ text = "|cffff4040" .. text .. "|r"
+ end
+ end
+ table.insert(parts, text)
+ end
+ return table.concat(parts, ", ")
+end
+
function MTH_BOOK_GetBeastZoneSummary(beast)
if not beast or not beast.coords or table.getn(beast.coords) == 0 then
return "-"
@@ -282,6 +309,22 @@ function MTH_BOOK_ParseBeastTraits(beast)
return traits
end
+-- "known" keeps beasts with at least one ability the hunter already knows;
+-- "unknown" keeps beasts that can still teach something not yet learned.
+function MTH_BOOK_BeastMatchesAbilityKnowledge(beast, mode)
+ if type(MTH_IsPetAbilityKnownByHunter) ~= "function" then return true end
+ local tokens = MTH_BOOK_SplitAbilities(beast and beast.abilities)
+ local n = table.getn(tokens)
+ if n == 0 then return false end
+ for i = 1, n do
+ local _, label, rank = MTH_BOOK_ParseAbilityToken(tokens[i])
+ local known = MTH_IsPetAbilityKnownByHunter(label, rank)
+ if mode == "known" and known then return true end
+ if mode == "unknown" and not known then return true end
+ end
+ return false
+end
+
function MTH_BOOK_BeastMatches(beastId, beast)
if not beast then return false end
local forcedBeastId = MTH_BOOK_STATE and tonumber(MTH_BOOK_STATE.forcedBeastId) or nil
@@ -305,6 +348,9 @@ function MTH_BOOK_BeastMatches(beastId, beast)
if not MTH_BOOK_HasKnownLevel(beast) then return false end
if not MTH_BOOK_HasKnownZone(beast) then return false end
end
+ if MTH_BOOK_STATE.petKnownFilter and MTH_BOOK_STATE.petKnownFilter ~= "all" then
+ if not MTH_BOOK_BeastMatchesAbilityKnowledge(beast, MTH_BOOK_STATE.petKnownFilter) then return false end
+ end
if MTH_BOOK_STATE.quick ~= "all" then
if familyLower ~= MTH_BOOK_STATE.quick then
diff --git a/api/hunterbook.lua b/api/hunterbook.lua
index 9f4c3b5..ec98403 100644
--- a/api/hunterbook.lua
+++ b/api/hunterbook.lua
@@ -137,6 +137,7 @@ local MTH_BOOK_STATE = {
familyStatsPercent = false,
petHideNoAbilities = true,
petHideUnknown = true,
+ petKnownFilter = "all",
trainerHonoredDiscount = false,
forcedBeastId = nil,
page = 1,
@@ -2336,6 +2337,28 @@ local function MTH_BOOK_UpdateRankDropdownText()
MTH_BOOK_DropdownSetText(rankDropdown, label)
end
+MTH_BOOK_PetKnownFilterOptions = {
+ { value = "all", label = "Known/Unknown" },
+ { value = "known", label = "Known Abilities" },
+ { value = "unknown", label = "Unknown Abilities" },
+}
+
+local function MTH_BOOK_GetKnownFilterLabel(value)
+ for i = 1, table.getn(MTH_BOOK_PetKnownFilterOptions) do
+ local option = MTH_BOOK_PetKnownFilterOptions[i]
+ if option and option.value == value then
+ return option.label
+ end
+ end
+ return "Known/Unknown"
+end
+
+local function MTH_BOOK_UpdateKnownFilterDropdownText()
+ local dropdown = getglobal("MTH_BOOK_KnownFilterDropdown")
+ if not dropdown then return end
+ MTH_BOOK_DropdownSetText(dropdown, MTH_BOOK_GetKnownFilterLabel(MTH_BOOK_STATE.petKnownFilter or "all"))
+end
+
local function MTH_BOOK_UpdatePetLearnSourceDropdownText()
local sourceDropdown = getglobal("MTH_BOOK_PetLearnSourceDropdown")
if not sourceDropdown then return end
@@ -2483,6 +2506,8 @@ local function MTH_BOOK_UpdateQuickFilterControls()
local petInZoneOnly = getglobal("MTH_BOOK_PetInZoneOnly")
local npcInZoneOnly = getglobal("MTH_BOOK_NPCInZoneOnly")
local showAllOnMapButton = getglobal("MTH_BOOK_ShowAllOnMapButton")
+ local knownFilterDropdown = getglobal("MTH_BOOK_KnownFilterDropdown")
+ if knownFilterDropdown then knownFilterDropdown:Hide() end
local minLevel = getglobal("MTH_BOOK_MinLevel")
local maxLevel = getglobal("MTH_BOOK_MaxLevel")
local stats = getglobal("MTH_BOOK_StatsText")
@@ -2577,6 +2602,10 @@ local function MTH_BOOK_UpdateQuickFilterControls()
rankDropdown:Hide()
end
end
+ if knownFilterDropdown then
+ knownFilterDropdown:Show()
+ MTH_BOOK_UpdateKnownFilterDropdownText()
+ end
if petInZoneOnly then
petInZoneOnly:Show()
petInZoneOnly:SetChecked(MTH_BOOK_STATE.petInZoneOnly and 1 or nil)
@@ -3063,6 +3092,33 @@ local function MTH_BOOK_InitRankDropdown()
MTH_BOOK_UpdateRankDropdownText()
end
+local function MTH_BOOK_InitKnownFilterDropdown()
+ local dropdown = getglobal("MTH_BOOK_KnownFilterDropdown")
+ if not dropdown then return end
+
+ UIDropDownMenu_Initialize(dropdown, function()
+ for i = 1, table.getn(MTH_BOOK_PetKnownFilterOptions) do
+ local option = MTH_BOOK_PetKnownFilterOptions[i]
+ local value = option.value
+ local label = option.label
+ local info = MTH_BOOK_DropdownCreateInfo()
+ info.text = label
+ info.func = function()
+ MTH_BOOK_STATE.petKnownFilter = value
+ MTH_BOOK_STATE.page = 1
+ MTH_BOOK_STATE.selectedEntry = nil
+ MTH_BOOK_DropdownSetText(dropdown, label)
+ MTH_BOOK_RefreshFilter()
+ end
+ info.checked = ((MTH_BOOK_STATE.petKnownFilter or "all") == value)
+ UIDropDownMenu_AddButton(info)
+ end
+ end)
+
+ UIDropDownMenu_SetWidth(140, dropdown)
+ UIDropDownMenu_JustifyText("LEFT", dropdown)
+ MTH_BOOK_UpdateKnownFilterDropdownText()
+end
local function MTH_BOOK_InitPetLearnSourceDropdown()
local sourceDropdown = getglobal("MTH_BOOK_PetLearnSourceDropdown")
@@ -4236,7 +4292,7 @@ local function MTH_BOOK_GetRowValues(entry)
if not beast then return { "", "", "", "", "", "", "", "", "", "" } end
local beastDisplayName = (MTH and MTH.GetLocalizedBeastName and MTH:GetLocalizedBeastName(entry, beast.name)) or beast.name
local traits = MTH_BOOK_ParseBeastTraits(beast)
- local abilities = MTH_BOOK_GetBeastAbilitiesSummary(beast)
+ local abilities = MTH_BOOK_GetBeastAbilitiesColored(beast)
local zone = MTH_BOOK_GetBeastZoneSummary(beast)
return {
"|cFF33CCFF" .. tostring(entry) .. "|r",
@@ -5209,6 +5265,7 @@ local function MTH_BOOK_ResetStateForMode(mode)
MTH_BOOK_STATE.npcHideNoZone = true
MTH_BOOK_STATE.petHideNoAbilities = false
MTH_BOOK_STATE.petHideUnknown = false
+ MTH_BOOK_STATE.petKnownFilter = "all"
MTH_BOOK_STATE.forcedBeastId = nil
MTH_BOOK_STATE.petLeftOffset = 0
@@ -5687,6 +5744,7 @@ local function MTH_BOOK_WireUI(frame)
MTH_BOOK_InitFamilyDropdown()
MTH_BOOK_InitAbilityDropdown()
MTH_BOOK_InitRankDropdown()
+ MTH_BOOK_InitKnownFilterDropdown()
MTH_BOOK_WireBeastDropdowns()
MTH_BOOK_InitPetLearnSourceDropdown()
MTH_BOOK_InitItemSubtypeDropdown()
diff --git a/api/hunterbook.xml b/api/hunterbook.xml
index 7da9855..4865778 100644
--- a/api/hunterbook.xml
+++ b/api/hunterbook.xml
@@ -289,15 +289,20 @@
+
+
+
+
+
-
+