diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c9f68b..9c3a4bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,19 +9,17 @@ Resurrecting on Octowow. ### Added -- **Hunter's Book - Hunter and Pet spells**: Added catalog pages for all Hunter and Pet Trainer spells, with spell icons, required level, base/Honored prices, branch, known status, search, level filters, sorting, and a scrollable inspector. +- **New spell datastore**: Metahunt now have a datastore of all twow 1.18.1 hunter and pet spells. And you can browse them with new pages in the Book. -- **Trainer cost planning**: Hunter's Book now shows a training plan with the cost of spells available now, the next training level, and all remaining spells. Prices can be switched between standard and Honored costs. +- **Trainer cost planning**: Added shared Hunter and Pet Trainer spell cost planning for spells available now, at the next training level, and still remaining. It powers Hunter's Book and Hunter level-up messages, with standard and Honored prices. -- **Live trainer status tracking**: Visiting a Hunter or Pet Trainer now records available, unavailable, and already-used services without guessing from filtered trainer lists. +- **Hunter and Pet spell scanning**: MetaHunt now reads your Hunter and Pet spellbooks to mark every spell rank you already know. When you visit a Hunter or Pet Trainer, it also records which ranks you can learn now and which ones are still unavailable. -- **Level-up tracking**: Added Hunter, Pet, and Pet Loyalty level-up notifications. Hunter messages list catalog spells unlocked at that level with base and Honored costs; major Hunter milestones use a special celebration. - -- **Leveling animation and message options**: Added separate Animation and Message controls for Hunter training levels, major milestones, pet training levels, and pet loyalty gains. +- **Level-up tracking**: Added Hunter, Pet, and Pet Loyalty level-up notifications. When you hit level, you can have a summary in the chat of all new spells available and their costs. - **Pet Auto-Teach — Growl**: When you tame a new beast, MetaHunt now offers to teach it Growl at the best rank for the pet's level. Click **Yes** and it opens the Beast Training window, teaches the ability and closes the window automatically. -- **Animations**: MetaHunt now plays optional animations that make the interface feel alive. Powered by the PizzaSauce library of [Pizzahawaii](https://codeberg.org/Pizzahawaii/) ! +- **Animations**: MetaHunt now plays optional animations that add fun and make the interface feel alive. Powered by the great PizzaSauce library of [Pizzahawaii](https://codeberg.org/Pizzahawaii/) ! Thank you man. - **zTrack — Find Fish**: Added new spell Find Fish to zTrack. @@ -33,6 +31,8 @@ Resurrecting on Octowow. - **Polished options**: The option panel had become messy overtime and it finally received some of attention to look cleaner and coherent with same styling everywhere and better arrangement. +- **Book navigation**: The book navigation is no longer done with horizontal tabs, but with a left vertical menu just like in the options. This allow more pages and fix the tab overfloading issues on some resolutions and UI scales. + ### Fixed - **Tooltips — your pet's info showing on other players**: In a party, mousing over or targeting another player could wrongly show YOUR pet's details (mood, loyalty, happiness, XP) on their tooltip. The own-pet detection no longer misfires on other units. diff --git a/README.MD b/README.MD index ffd4f81..e9cc297 100644 --- a/README.MD +++ b/README.MD @@ -21,6 +21,7 @@ MetaHunt ships with large twow datastores, and notably: - 100% accurate beasts' data, their locations, and the abilities they can learn you - All Pet families, their abilities and their diet - All pet abilities ranks +- All hunter and pet spells - All Ammo and ranged weapons - All Hunter/Pet/Stable Masters - All Ammo vendors @@ -82,6 +83,14 @@ Define your own simple rules for auto buy ammo and pet food when you open a vend Just spam SHIFT-click on the NPC to validate quests Scorpok and Thorium arrows. Additionally you can have an enhanced tooltip that display your actual Scorpok-related items when you mouseover the Blasted Land mobs involved. + ## Efficient Scanners + +The add-on smartly scan your character and pet tabs, spellbook, beast training, stable and learning masters windows. This is done automatically and fast in the background, and allows to enrich the static datastore with YOUR own data, and to provide meaningfull dynamic information following the context. It also scan your Pet's state constantly, but with minimal ressources. + + ## Animations + +Metahunt is the first add-on that uses the great PizzaSauce library of [Pizzahawaii](https://codeberg.org/Pizzahawaii/). This adds fun and makes the interface feel alive. + ## The Great Book of Huntards The Book is the main GUI of MetaHunt, it allows to browse the addon's data to find anything a Hunter needs. @@ -93,6 +102,7 @@ Just spam SHIFT-click on the NPC to validate quests Scorpok and Thorium arrows. - Display meaningfully the pet abilities that you know and don't know yet - Get your stable's state everywhere and track all possible information about all your pets - Keep a detailed history of all the pets you abandonned or those that ran away. +- Browse all twow 1.18.1 hunter and pet spells. Get the status of what you already learned or not, and a detailed cost planning. ## Tune it the way you like @@ -100,5 +110,5 @@ Metahunt option panel is huge. There are hundreds of settings you can configure Its modular architecture also allows you to completely disable any module in order to decrease the addon's memory footprint and background processes. - ### Happy Hunting Fellas ! + ### The world is yours. Happy Hunting Fellas ! diff --git a/api/core-level-tracking.lua b/api/core-level-tracking.lua index d0fedaf..935d8d5 100644 --- a/api/core-level-tracking.lua +++ b/api/core-level-tracking.lua @@ -96,11 +96,11 @@ local MTH_LT_PetLines = { } local MTH_LT_LoyaltyLines = { - "has decided you are less terrible than expected.", - "has upgraded its opinion of you. Keep the food coming.", - "is learning to trust your decision-making. This may be a mistake.", - "has accepted the arrangement. The arrangement includes snacks.", - "now trusts you more. Do not immediately test this with a cliff.", + [2] = "is now Unruly. It tolerates your leadership as long as the food arrives on time.", + [3] = "is now Submissive. Your authority has been acknowledged, reluctantly.", + [4] = "is now Dependable. It has decided your plans are survivable often enough.", + [5] = "is now Faithful. Please do not reward this trust with an elite pull.", + [6] = "is your Best Friend. Against all evidence, it trusts you completely.", } local function MTH_LT_Store() @@ -154,6 +154,43 @@ local function MTH_LT_FormatRows(plan) return table.concat(labels, ", ") end +local function MTH_LT_GrowlRankForLevel(level) + local rank = math.floor((tonumber(level) or 1) / 10) + 1 + if rank < 1 then rank = 1 end + if rank > 7 then rank = 7 end + return rank +end + +local function MTH_LT_BuildPetGrowlPlan(level, preview, honored) + if type(MTH_TrainerPlan_BuildLevel) ~= "function" then return nil end + local plan = MTH_TrainerPlan_BuildLevel("pet", level, { honored = honored and true or false, includeKnown = preview }) + local growlPlan = { + rows = {}, + unlearned = { count = 0, cost = 0 }, + } + for _, entry in ipairs(plan.rows or {}) do + if tostring(entry.row and entry.row.name or "") == "Growl" then + table.insert(growlPlan.rows, entry) + growlPlan.unlearned.count = growlPlan.unlearned.count + 1 + growlPlan.unlearned.cost = growlPlan.unlearned.cost + (tonumber(entry.price) or 0) + end + end + return growlPlan +end + +local function MTH_LT_HandlePetGrowlLevel(petName, level) + if level < 10 or level > 60 or math.mod(level, 10) ~= 0 then return end + local rank = MTH_LT_GrowlRankForLevel(level) + local known = type(MTH_HT_GetSpellInfo) == "function" and MTH_HT_GetSpellInfo("Growl") or nil + if known and (tonumber(known.rankNum) or 0) >= rank then + if type(MTH_Growl_OfferForTamedPet) == "function" then + MTH_Growl_OfferForTamedPet(petName, level) + end + elseif MTH_LT_MessageEnabled("petLevelUp", true) then + MTH:Print(petName .. " can now learn Growl Rank " .. tostring(rank) .. ". Visit a Pet Trainer to learn it.") + end +end + local function MTH_LT_PrintSpellList(plan) local line = "" local isFirstLine = true @@ -190,6 +227,9 @@ local function MTH_LT_AnnounceTraining(kind, level, eventKind, preview) if headline and headline.row and headline.row.rank and headline.row.rank ~= "" then headlineText = headlineText .. " " .. headline.row.rank end local isLevelCap = kind == "hunter" and level == 60 if isLevelCap then headlineText = "The hunt is yours" end + local isPetGrowlMilestone = kind == "pet" and level >= 10 and level <= 60 and math.mod(level, 10) == 0 + if isPetGrowlMilestone then headlineText = "Growl Rank " .. tostring(MTH_LT_GrowlRankForLevel(level)) end + if kind == "hunter" and not isLevelCap then headlineText = nil end if MTH_LT_MessageEnabled(eventKind == "hunter" and "hunterLevelUp" or "petLevelUp", true) then if kind == "hunter" then MTH:Print("Congratz! You hit level " .. tostring(level) .. ".") @@ -198,8 +238,12 @@ local function MTH_LT_AnnounceTraining(kind, level, eventKind, preview) .. ", but only " .. MTH_LT_FormatCost(honored.unlearned.cost) .. " if you are Honored with the master.") MTH_LT_PrintSpellList(base) else - MTH:Print("" .. MTH_LT_FormatRows(base)) - MTH:Print("Trainer cost: Base " .. MTH_LT_FormatCost(base.unlearned.cost) .. " | Honored " .. MTH_LT_FormatCost(honored.unlearned.cost)) + local displayPlan = isPetGrowlMilestone and MTH_LT_BuildPetGrowlPlan(level, preview) or base + local displayHonoredPlan = isPetGrowlMilestone and MTH_LT_BuildPetGrowlPlan(level, preview, true) or honored + if displayPlan and displayPlan.unlearned.count > 0 then + MTH:Print(MTH_LT_FormatRows(displayPlan)) + MTH:Print("Trainer cost: Base " .. MTH_LT_FormatCost(displayPlan.unlearned.cost) .. " | Honored " .. MTH_LT_FormatCost(displayHonoredPlan.unlearned.cost)) + end end end local isMilestone = kind == "hunter" and (level == 10 or level == 20 or level == 30 or level == 40 or level == 50 or level == 60) @@ -207,9 +251,10 @@ local function MTH_LT_AnnounceTraining(kind, level, eventKind, preview) if type(MTH_FX_IsEnabled) == "function" and MTH_FX_IsEnabled(flag) and type(MTH_Celebrate) == "function" then local subtitle = kind == "hunter" and (MTH_LT_HunterLines[level] or "New training is available.") or "New pet training is available. The trainer wants coin." if isMilestone and type(MTH_CelebrateBlackHole) == "function" then - MTH_CelebrateBlackHole("Level " .. tostring(level) .. " - " .. headlineText, subtitle) + MTH_CelebrateBlackHole(isLevelCap and headlineText or "Level " .. tostring(level), subtitle) else - MTH_Celebrate("Level " .. tostring(level) .. " - " .. headlineText, subtitle, "fanfare", 4.8) + local title = headlineText and ("Level " .. tostring(level) .. " - " .. headlineText) or "Level " .. tostring(level) + MTH_Celebrate(title, subtitle, "fanfare", 5) end end end @@ -248,10 +293,10 @@ local function MTH_LT_HandlePetState() local line = MTH_LT_NextLine(store, "petLine", MTH_LT_PetLines) if MTH_LT_MessageEnabled("petLevelUp", true) then MTH:Print(state.name .. " reached level " .. state.level .. ". " .. line) end MTH_LT_AnnounceTraining("pet", state.level, "pet") + MTH_LT_HandlePetGrowlLevel(state.name, state.level) end - if state.loyalty and state.loyalty > (tonumber(pet.loyalty) or 0) then - local line = MTH_LT_NextLine(store, "loyaltyLine", MTH_LT_LoyaltyLines) - if state.loyalty == 6 then line = "is your Best Friend. Against all evidence, it trusts you completely." end + if state.loyalty and state.loyalty > 1 and state.loyalty > (tonumber(pet.loyalty) or 0) then + local line = MTH_LT_LoyaltyLines[state.loyalty] or "has gained a loyalty level. The food arrangement appears to be working." if MTH_LT_MessageEnabled("petLoyaltyUp", true) then MTH:Print(state.name .. " reached Loyalty Level " .. state.loyalty .. ". " .. line) end if type(MTH_FX_IsEnabled) == "function" and MTH_FX_IsEnabled("level.loyalty") and type(MTH_Celebrate) == "function" then MTH_Celebrate(state.name .. " - Loyalty " .. state.loyalty, line, state.loyalty == 6 and "victory" or "fanfare") @@ -283,9 +328,12 @@ function MTH_LevelTracker_Test(kind, level) if kind == "loyalty" then local state = MTH_LT_GetPetState() local loyalty = tonumber(level) or (state and state.loyalty) or 1 + if loyalty <= 1 then + MTH:Print("Pet Loyalty starts at level 1 when you tame a pet. Test levels 2 through 6.") + return false + end local petName = state and state.name or "Your pet" - local line = loyalty == 6 and "is your Best Friend. Against all evidence, it trusts you completely." - or MTH_LT_LoyaltyLines[1] + local line = MTH_LT_LoyaltyLines[loyalty] or "has gained a loyalty level. The food arrangement appears to be working." MTH:Print(petName .. " reached Loyalty Level " .. tostring(loyalty) .. ". " .. line) if type(MTH_Celebrate) == "function" then MTH_Celebrate(petName .. " - Loyalty " .. tostring(loyalty), line, loyalty == 6 and "victory" or "fanfare") diff --git a/api/fx-celebrate.lua b/api/fx-celebrate.lua index 2bb1fff..12d9ce7 100644 --- a/api/fx-celebrate.lua +++ b/api/fx-celebrate.lua @@ -413,7 +413,7 @@ function MTH_Celebrate(title, subtitle, style, displaySeconds) return end style = string.lower(tostring(style or "firework")) - local fadeDelay = tonumber(displaySeconds) or 2.1 + local fadeDelay = tonumber(displaySeconds) or 5 if fadeDelay < 0.5 then fadeDelay = 0.5 end if style == "starfall" then @@ -536,7 +536,7 @@ local function MTH_FX_ShowPreviewBanner(title, subtitle, r, g, b) Sauce:FadeTo(MTH_FX_MsgFrame, 1, 0.18), Sauce:Pulse(MTH_FX_MsgFrame, 1.18, 0.45), }), - Sauce:FadeOut(MTH_FX_MsgFrame, 0.55, "inQuad", { delay = 2.1 }), + Sauce:FadeOut(MTH_FX_MsgFrame, 0.55, "inQuad", { delay = 5 }), }) end @@ -695,7 +695,7 @@ function MTH_CelebratePreview(style) table.insert(steps, Sauce:Run(function() MTH_CelebratePreview(previewStyle) end, { defer = true })) - table.insert(steps, Sauce:Delay(3.7)) + table.insert(steps, Sauce:Delay(5.7)) i = i + 1 end Sauce:Sequence(steps)