Animations: wire remaining effects + 2-column options panel

- Shared FX toolkit in fx-celebrate.lua: mth_shake tween type, MTH_FX_Flash
  glow helper, MTH_CelebrateRunaway red shaking banner, gold title reset.
- pet.runaway, pet.happiness, pet.loyaltyup, pet.feed
- combat.ammoswap, combat.rangedswap, combat.mmprocs
- ui.zbar, ui.stable, ui.minimapping, ui.optionsclose
- book.model, book.search
- Options > Animations panel now uses a balanced two-column layout.
- CHANGELOG Animations entry expanded (no version bump).
This commit is contained in:
DuvelCorp
2026-09-10 16:38:14 +02:00
parent d2fb04f7c5
commit 66ff1ae711
14 changed files with 343 additions and 11 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ Resurrecting on Octowow.
### Added
- **Animations**: MetaHunt now plays optional animations that make the interface feel alive. A firework-and-banner celebration bursts on screen when your pet learns a new ability or a new rank, the Great Book slides up and fades in when you open it and gently fades its list when you switch tabs, the options window slides in when opened and its tabs fade as you switch them, the minimap button pulses when clicked, collapsible zButton bars fade their buttons in as they expand, and world-map markers fade in when you locate a beast, vendor or master. Everything is optional and off-switchable: a new **Animations** tab (Options → Animations) lets you toggle each effect on its own — or disable them all at once. Powered by the PizzaSauce animation library.
- **Animations**: MetaHunt now plays optional animations that make the interface feel alive. A firework-and-banner celebration bursts on screen when your pet learns a new ability or a new rank, and a red shaking banner warns you when a pet runs away for good. Your pet button flashes when its happiness changes, it gains a loyalty level, or you feed it; the ammo button flashes when Smart Ammo swaps your bullets or auto-equips after a weapon swap; and the MM Widget pulses on a Lock & Load proc. The Great Book slides up and fades in when you open it, gently fades its list when you switch tabs or run a search, fades beast models into view, and fades out when closed; stable slots flash when a pet is deposited, withdrawn or swapped. The options window slides in when opened, fades its tabs as you switch them, and fades out when closed. The minimap button pulses when clicked, minimap markers ping as beasts come into range, collapsible zButton bars fade their buttons in as they expand, the zBar fades in when enabled, and world-map markers fade in when you locate a beast, vendor or master. Everything is optional and off-switchable: a new **Animations** tab (Options → Animations) lets you toggle each effect on its own — or disable them all at once. Powered by the PizzaSauce animation library.
- **zTrack — Find Fish**: Added new spell Find Fish to the zTrack list of trackings.
+7
View File
@@ -1385,6 +1385,13 @@ function MTH_FEED_FinalizeAttempt(attemptId, payload)
if petKey ~= "" then
MTH_FEED_Runtime.sessionFeedsByPetId[petKey] = (tonumber(MTH_FEED_Runtime.sessionFeedsByPetId[petKey]) or 0) + 1
end
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function"
and MTH_FX_IsEnabled("pet.feed") then
local target = getglobal("zButtonPet")
if target then
MTH_FX_Flash(target, 0.35, 1.00, 0.35, 0.5)
end
end
else
petRow.totals.rejected = petRow.totals.rejected + 1
if reason == "no-buff" then
+3
View File
@@ -2791,6 +2791,9 @@ function MTH_PETS_RecordPetRunaway(source, rawMessage)
if MTH:IsMessageEnabled("petRanAway", true) then
MTH:Print("YOUR PET " .. tostring(displayName) .. " HAS RUNAWAY FOREVER :-( Try to feed it better next time.")
end
if type(MTH_CelebrateRunaway) == "function" then
MTH_CelebrateRunaway(displayName)
end
end
return true
+144
View File
@@ -33,6 +33,7 @@ MTH_FX_DBG = {
-- Sections shown, in order, in the options panel. `titleKey` localizes `title`.
MTH_FX_ANIM_SECTIONS = {
{ id = "pet", title = "Pet", titleKey = "ANIM_SECTION_PET" },
{ id = "combat", title = "Combat", titleKey = "ANIM_SECTION_COMBAT" },
{ id = "book", title = "Book", titleKey = "ANIM_SECTION_BOOK" },
{ id = "ui", title = "Interface", titleKey = "ANIM_SECTION_UI" },
}
@@ -46,6 +47,34 @@ MTH_FX_ANIM_DEFS = {
label = "Celebrate new pet abilities", labelKey = "ANIM_PET_CELEBRATE",
tooltip = "Play a firework and a banner in the middle of the screen when your pet learns a new ability or a new rank.",
tooltipKey = "ANIM_PET_CELEBRATE_TIP" },
{ key = "pet.runaway", section = "pet", default = true,
label = "Warn when a pet runs away", labelKey = "ANIM_PET_RUNAWAY",
tooltip = "Flash a red, shaking banner in the middle of the screen when one of your pets runs away for good.",
tooltipKey = "ANIM_PET_RUNAWAY_TIP" },
{ key = "pet.happiness", section = "pet", default = true,
label = "Flash on happiness change", labelKey = "ANIM_PET_HAPPINESS",
tooltip = "Briefly flash the pet happiness area green when your pet cheers up, or red when it gets unhappy.",
tooltipKey = "ANIM_PET_HAPPINESS_TIP" },
{ key = "pet.loyaltyup", section = "pet", default = true,
label = "Glow on loyalty gain", labelKey = "ANIM_PET_LOYALTYUP",
tooltip = "Give a short golden glow when your pet gains a loyalty level.",
tooltipKey = "ANIM_PET_LOYALTYUP_TIP" },
{ key = "pet.feed", section = "pet", default = true,
label = "Flash when feeding your pet", labelKey = "ANIM_PET_FEED",
tooltip = "Give a short green flash when Feed-O-Matic feeds your pet.",
tooltipKey = "ANIM_PET_FEED_TIP" },
{ key = "combat.ammoswap", section = "combat", default = true,
label = "Flash on Smart Ammo swap", labelKey = "ANIM_COMBAT_AMMOSWAP",
tooltip = "Briefly highlight the zAmmo button when Smart Ammo swaps your ammo.",
tooltipKey = "ANIM_COMBAT_AMMOSWAP_TIP" },
{ key = "combat.rangedswap", section = "combat", default = true,
label = "Flash on ranged weapon swap", labelKey = "ANIM_COMBAT_RANGEDSWAP",
tooltip = "Briefly highlight the zRanged button when you hot-swap a ranged weapon.",
tooltipKey = "ANIM_COMBAT_RANGEDSWAP_TIP" },
{ key = "combat.mmprocs", section = "combat", default = true,
label = "Pulse MM Widget procs", labelKey = "ANIM_COMBAT_MMPROCS",
tooltip = "Pulse an MM Widget cell when a Lock and Load or Experimental ammo proc lights up.",
tooltipKey = "ANIM_COMBAT_MMPROCS_TIP" },
{ key = "book.open", section = "book", default = true,
label = "Fade in the Hunter's Book", labelKey = "ANIM_BOOK_OPEN",
tooltip = "Fade the Hunter's Book window in when you open it.",
@@ -54,6 +83,14 @@ MTH_FX_ANIM_DEFS = {
label = "Fade Hunter's Book tab changes", labelKey = "ANIM_BOOK_TABS",
tooltip = "Fade the results list back in when you switch tabs inside the Hunter's Book.",
tooltipKey = "ANIM_BOOK_TABS_TIP" },
{ key = "book.model", section = "book", default = true,
label = "Fade in beast models", labelKey = "ANIM_BOOK_MODEL",
tooltip = "Fade the beast model viewer in when it loads a new model.",
tooltipKey = "ANIM_BOOK_MODEL_TIP" },
{ key = "book.search", section = "book", default = true,
label = "Fade search results", labelKey = "ANIM_BOOK_SEARCH",
tooltip = "Fade the results list when your search filter changes.",
tooltipKey = "ANIM_BOOK_SEARCH_TIP" },
{ key = "ui.options", section = "ui", default = true,
label = "Slide the options window open", labelKey = "ANIM_UI_OPTIONS",
tooltip = "Slide and fade the MetaHunt options window in when you open it.",
@@ -62,14 +99,30 @@ MTH_FX_ANIM_DEFS = {
label = "Fade options tab changes", labelKey = "ANIM_UI_OPTIONTABS",
tooltip = "Fade the settings panel when you switch tabs inside the options window.",
tooltipKey = "ANIM_UI_OPTIONTABS_TIP" },
{ key = "ui.optionsclose", section = "ui", default = true,
label = "Fade windows closed", labelKey = "ANIM_UI_OPTIONSCLOSE",
tooltip = "Fade the options and Hunter's Book windows out when you close them.",
tooltipKey = "ANIM_UI_OPTIONSCLOSE_TIP" },
{ key = "ui.minimap", section = "ui", default = true,
label = "Pulse the minimap button on click", labelKey = "ANIM_UI_MINIMAP",
tooltip = "Give the minimap button a quick pulse when you click it.",
tooltipKey = "ANIM_UI_MINIMAP_TIP" },
{ key = "ui.minimapping", section = "ui", default = true,
label = "Ping the minimap on locate", labelKey = "ANIM_UI_MINIMAPPING",
tooltip = "Send a short ping ripple over the minimap when you locate a tracked NPC.",
tooltipKey = "ANIM_UI_MINIMAPPING_TIP" },
{ key = "ui.zbuttons", section = "ui", default = true,
label = "Fade zButton bars open", labelKey = "ANIM_UI_ZBUTTONS",
tooltip = "Fade the child buttons in when a collapsible zButton bar (pet, tracking, aspects...) expands.",
tooltipKey = "ANIM_UI_ZBUTTONS_TIP" },
{ key = "ui.zbar", section = "ui", default = true,
label = "Fade the zBar in", labelKey = "ANIM_UI_ZBAR",
tooltip = "Fade the unified zBar buttons in when the bar becomes active.",
tooltipKey = "ANIM_UI_ZBAR_TIP" },
{ key = "ui.stable", section = "ui", default = true,
label = "Flash stable slots on change", labelKey = "ANIM_UI_STABLE",
tooltip = "Flash a stable slot in the Hunter's Book when a pet is deposited or withdrawn.",
tooltipKey = "ANIM_UI_STABLE_TIP" },
{ key = "ui.mappins", section = "ui", default = true,
label = "Fade map markers in", labelKey = "ANIM_UI_MAPPINS",
tooltip = "Fade the world map markers in when you locate a beast, vendor or master.",
@@ -166,6 +219,63 @@ else
end
MTH_FX_DBG.step = "3-after-registertype"
-- Register a decaying "shake" tween type: oscillates the frame around its own
-- current anchor point, with the amplitude fading to zero over the tween so it
-- always lands back exactly where it started. Used for negative events.
if Sauce and type(Sauce.RegisterType) == "function" and not Sauce.MTH_HasShake then
local ok, err = pcall(function()
Sauce.MTH_HasShake = true
Sauce:RegisterType("mth_shake", {
init = function(target)
local p, rel, rp, x, y = target:GetPoint(1)
return { p or "CENTER", rel, rp or p or "CENTER", x or 0, y or 0 }
end,
apply = function(target, from, to, t, tween)
local mag = tween.magnitude or 8
local freq = tween.freq or 34
local decay = 1 - t
local offset = math.sin(t * freq) * mag * decay
target:ClearAllPoints()
target:SetPoint(from[1], from[2], from[3], (from[4] or 0) + offset, from[5] or 0)
end,
})
end)
MTH_FX_DBG.shakeOk = ok
MTH_FX_DBG.shakeErr = err
end
-- Reusable flash: overlays a short additive colour glow on any frame/button and
-- fades it out. Safe on any frame that supports CreateTexture; silent no-op
-- otherwise. The overlay texture is cached on the frame for reuse.
function MTH_FX_Flash(frame, r, g, b, duration)
if not Sauce or not frame then
return
end
if type(frame.CreateTexture) ~= "function" then
return
end
local tex = frame.mthFxFlash
if not tex then
tex = frame:CreateTexture(nil, "OVERLAY")
tex:SetTexture("Interface\\Buttons\\CheckButtonHilight")
tex:SetBlendMode("ADD")
tex:SetAllPoints(frame)
frame.mthFxFlash = tex
end
tex:SetVertexColor(r or 1, g or 1, b or 1)
tex:SetAlpha(0)
tex:Show()
local dur = duration or 0.45
Sauce:Stop(tex)
Sauce:Sequence({
Sauce:FadeTo(tex, 0.85, dur * 0.35),
Sauce:FadeTo(tex, 0, dur * 0.65, "inQuad", {
onFinish = function() tex:Hide() end,
}),
})
end
local MTH_FX_NUM_SPARKS = 22
local MTH_FX_Container
local MTH_FX_MsgFrame
@@ -240,6 +350,7 @@ function MTH_Celebrate(title, subtitle)
return
end
MTH_FX_TitleFS:SetTextColor(1, 0.82, 0)
MTH_FX_TitleFS:SetText(title or "")
MTH_FX_SubFS:SetText(subtitle or "")
@@ -305,6 +416,39 @@ function MTH_CelebratePetAbility(label)
MTH_Celebrate(MTH_FX_L("ANIM_PET_LEARNED_TITLE", "New Pet Ability!"), label)
end
-- Dramatic negative banner: a red, shaking message shown when a pet runs away
-- for good. Gated on pet.runaway. Reuses the shared message frame.
function MTH_CelebrateRunaway(petName)
if not MTH_FX_IsEnabled("pet.runaway") then
return
end
if not Sauce then
return
end
if not MTH_FX_EnsureFrames() then
return
end
MTH_FX_TitleFS:SetTextColor(1, 0.15, 0.15)
MTH_FX_TitleFS:SetText(MTH_FX_L("ANIM_PET_RUNAWAY_TITLE", "Your pet ran away!"))
MTH_FX_SubFS:SetText(petName or "")
Sauce:Stop(MTH_FX_MsgFrame)
MTH_FX_MsgFrame:SetAlpha(0)
MTH_FX_MsgFrame:Show()
Sauce:Sequence({
Sauce:FadeTo(MTH_FX_MsgFrame, 1, 0.18),
Sauce:Tween(MTH_FX_MsgFrame, {
type = "mth_shake",
duration = 0.55,
easing = "linear",
magnitude = 11,
freq = 42,
}),
Sauce:FadeOut(MTH_FX_MsgFrame, 0.7, "inQuad", { delay = 1.6 }),
})
end
-- DEBUG: mark that the whole file finished loading and record which globals it
-- successfully defined. TEMP diagnostic.
MTH_FX_DBG.step = "4-complete"
+14
View File
@@ -6,6 +6,18 @@
-- Uses MTH_DS_BeastSkins[familyName] generated by .tools/generators/gen_beast_skins.py
-- Skin rendering: PlayerModel:SetUnit(CreatureDisplayInfo.ID)
local MTH_MV_Sauce = PizzaSauce
-- Fade a model frame in when a new skin is displayed, unless disabled.
local function MTH_MV_AnimateModel(model)
if not MTH_MV_Sauce or not model then return end
if type(MTH_FX_IsEnabled) == "function" and not MTH_FX_IsEnabled("book.model") then return end
if type(model.SetAlpha) ~= "function" then return end
if not model:IsShown() then return end
model:SetAlpha(0)
MTH_MV_Sauce:FadeTo(model, 1, 0.30, "outQuad")
end
local MTH_MV = {
inited = false,
family = nil,
@@ -51,6 +63,8 @@ local function MTH_MV_DisplayCurrent()
MTH_MV_ApplyModel(MTH_MV.previewModel, skin.id)
MTH_MV_ApplyModel(MTH_MV.popupModel, skin.id)
MTH_MV_AnimateModel(MTH_MV.previewModel)
MTH_MV_AnimateModel(MTH_MV.popupModel)
local indexStr = tostring(MTH_MV.index) .. " / " .. tostring(n)
if MTH_MV.popupSkinLabel then
+11
View File
@@ -1245,6 +1245,17 @@ function MTH_BOOKTAB_RenderStableCards()
local row = slotEntry and slotEntry.row or nil
MTH_BOOK_DebugTrace("Render card#" .. tostring(i) .. " petId=" .. tostring(petId) .. " hasRow=" .. tostring(type(row) == "table"))
-- Animations: flash the slot when its occupant changes (deposit /
-- withdraw / swap), but never on the first render of this card.
if card._stableInit and card._lastStablePetId ~= petId then
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function"
and MTH_FX_IsEnabled("ui.stable") then
MTH_FX_Flash(card, 1.00, 0.82, 0.20, 0.55)
end
end
card._lastStablePetId = petId
card._stableInit = true
card:ClearAllPoints()
card:SetPoint("TOPLEFT", ui.frame, "TOPLEFT", 8, y)
card:SetPoint("TOPRIGHT", ui.frame, "TOPRIGHT", -8, y)
+31 -2
View File
@@ -29,6 +29,34 @@ local function MTH_BOOK_AnimateTabSwitch()
Sauce:FadeIn(list, 0.25)
end
-- Fade the book window out before hiding it, unless disabled (shares the
-- "fade windows closed" toggle with the options window).
local function MTH_BOOK_FadeOutWindow(frame)
if not frame then return end
if not Sauce
or (type(MTH_FX_IsEnabled) == "function" and not MTH_FX_IsEnabled("ui.optionsclose")) then
if type(frame.SetAlpha) == "function" then frame:SetAlpha(1) end
frame:Hide()
return
end
Sauce:FadeOut(frame, 0.22, "inQuad", {
onFinish = function()
frame:Hide()
if type(frame.SetAlpha) == "function" then frame:SetAlpha(1) end
end,
})
end
-- Fade the results list back in after a search/filter is applied, unless disabled.
local function MTH_BOOK_AnimateSearchResults()
if not Sauce then return end
if type(MTH_FX_IsEnabled) == "function" and not MTH_FX_IsEnabled("book.search") then return end
local list = getglobal("MTH_BOOK_ListBackdrop")
if not list then return end
if type(list.SetAlpha) == "function" then list:SetAlpha(0) end
Sauce:FadeIn(list, 0.22)
end
MTH_HUNTERBOOK_LOADED = true
MTH_HUNTERBOOK_TABS = MTH_HUNTERBOOK_TABS or {}
@@ -4719,6 +4747,7 @@ local function MTH_BOOK_ApplyInputs()
MTH_BOOK_STATE.selectedPetRankEntry = nil
MTH_BOOK_STATE.petRankRows = {}
MTH_BOOK_RefreshFilter()
MTH_BOOK_AnimateSearchResults()
end
local function MTH_BOOK_SetQuickFilter(index)
@@ -5301,7 +5330,7 @@ local function MTH_BOOK_WireUI(frame)
closeButton:SetWidth(22)
closeButton:SetHeight(22)
closeButton:SetText("X")
closeButton:SetScript("OnClick", function() this:GetParent():Hide() end)
closeButton:SetScript("OnClick", function() MTH_BOOK_FadeOutWindow(this:GetParent()) end)
end
if applyButton then applyButton:SetScript("OnClick", MTH_BOOK_ApplyInputs) end
@@ -5752,7 +5781,7 @@ function MTH_ToggleHunterBook()
local frame = MTH_BOOK_EnsureWindow()
if not frame then return end
if frame:IsShown() then
frame:Hide()
MTH_BOOK_FadeOutWindow(frame)
else
frame:Show()
MTH_BOOK_FadeInWindow(frame)
+19
View File
@@ -38,6 +38,15 @@ local function MTH_Map_AnimatePin(pin)
MTH_MAP_Sauce:FadeIn(pin, 0.3)
end
-- Ping a minimap pin that just came into range. Only called for genuinely new
-- nodes (see UpdateMinimap), never every tick, to avoid strobing.
local function MTH_Map_PingMinimapPin(pin)
if not MTH_MAP_Sauce or not pin then return end
if type(MTH_FX_IsEnabled) == "function" and not MTH_FX_IsEnabled("ui.minimapping") then return end
if type(pin.SetAlpha) == "function" then pin:SetAlpha(0) end
MTH_MAP_Sauce:FadeIn(pin, 0.35)
end
local MTH_MAP_MINIMAP_ZOOM = {
[0] = { [0] = 300, [1] = 240, [2] = 180, [3] = 120, [4] = 80, [5] = 50 },
[1] = { [0] = 466 + 2/3, [1] = 400, [2] = 333 + 1/3, [3] = 266 + 2/6, [4] = 200, [5] = 133 + 1/3 },
@@ -948,6 +957,7 @@ function MTH_Map:HideMinimapPins()
for i = 1, table.getn(self.minimapPins) do
if self.minimapPins[i] then self.minimapPins[i]:Hide() end
end
self._miniShownSet = nil
end
function MTH_Map:HideAllPins()
@@ -1161,6 +1171,8 @@ function MTH_Map:UpdateMinimap()
local xDraw = Minimap:GetWidth() / xScale / 100
local yDraw = Minimap:GetHeight() / yScale / 100
local shown = 0
local prevShown = self._miniShownSet or {}
local nowShown = {}
for i = 1, table.getn(nodes) do
local node = nodes[i]
@@ -1182,9 +1194,16 @@ function MTH_Map:UpdateMinimap()
pin:ClearAllPoints()
pin:SetPoint("CENTER", Minimap, "CENTER", xPos, -yPos)
pin:Show()
local nodeKey = tostring(node.name or "") .. "@" .. tostring(node.x) .. "," .. tostring(node.y)
nowShown[nodeKey] = true
if not prevShown[nodeKey] then
MTH_Map_PingMinimapPin(pin)
end
end
end
end
self._miniShownSet = nowShown
for i = shown + 1, table.getn(self.minimapPins) do
if self.minimapPins[i] then self.minimapPins[i]:Hide() end
+19 -7
View File
@@ -120,25 +120,37 @@ function MTH_SetupAnimationsOptions()
end)
end
-- Per-animation checkboxes, grouped by section.
local y = -104
-- Per-animation checkboxes, grouped by section, laid out in two columns.
-- Each whole section is placed into whichever column is currently shorter
-- (largest remaining Y), so the two columns stay balanced as defs grow.
local rowStep = 26
local sectionGap = 12
local columns = {
{ headerX = 15, cbX = 28, y = -104 },
{ headerX = 300, cbX = 313, y = -104 },
}
local s = 1
while MTH_FX_ANIM_SECTIONS and s <= table.getn(MTH_FX_ANIM_SECTIONS) do
local sec = MTH_FX_ANIM_SECTIONS[s]
-- Pick the shorter column (the one whose cursor is nearest the top).
local col = columns[1]
if columns[2].y > columns[1].y then
col = columns[2]
end
local header = container:CreateFontString(nil, "ARTWORK", "GameFontNormal")
header:SetPoint("TOPLEFT", container, "TOPLEFT", 15, y)
header:SetPoint("TOPLEFT", container, "TOPLEFT", col.headerX, col.y)
header:SetText(MTH_ANIM_L(sec.titleKey, sec.title))
header:SetTextColor(1.00, 0.82, 0.00)
y = y - 22
col.y = col.y - 22
local d = 1
while MTH_FX_ANIM_DEFS and d <= table.getn(MTH_FX_ANIM_DEFS) do
local def = MTH_FX_ANIM_DEFS[d]
if def.section == sec.id then
local cbName = "MetaHuntOptionsAnim_" .. string.gsub(def.key, "%.", "_")
local cb = MTH_CreateCheckbox(container, cbName, MTH_ANIM_L(def.labelKey, def.label), y, 28)
local cb = MTH_CreateCheckbox(container, cbName, MTH_ANIM_L(def.labelKey, def.label), col.y, col.cbX)
if cb then
cb.mthKey = def.key
cb:SetChecked(MTH_FX_GetFlag(def.key))
@@ -155,12 +167,12 @@ function MTH_SetupAnimationsOptions()
cb:SetScript("OnLeave", function() GameTooltip:Hide() end)
end
table.insert(MTH_ANIM_CTRL, cb)
y = y - rowStep
col.y = col.y - rowStep
end
end
d = d + 1
end
y = y - sectionGap
col.y = col.y - sectionGap
s = s + 1
end
+19 -1
View File
@@ -47,6 +47,24 @@ local function MTH_OPT_AnimateTabContent(tabKey)
end
end
-- Fade the options window out before hiding it, unless disabled.
local function MTH_OPT_AnimateClose()
local frame = MetaHuntOptions
if not frame then return end
if not MTH_OPT_Sauce
or (type(MTH_FX_IsEnabled) == "function" and not MTH_FX_IsEnabled("ui.optionsclose")) then
frame:SetAlpha(1)
frame:Hide()
return
end
MTH_OPT_Sauce:FadeOut(frame, 0.22, "inQuad", {
onFinish = function()
frame:Hide()
frame:SetAlpha(1)
end,
})
end
local function MTH_RegisterEscClose(frameName)
if not (frameName and UISpecialFrames) then
return
@@ -103,7 +121,7 @@ local function MTH_EnsureOptionsFrame()
closeBtn:SetWidth(MTH_OPTIONS_CONST.CLOSE_BTN_SIZE)
closeBtn:SetHeight(MTH_OPTIONS_CONST.CLOSE_BTN_SIZE)
closeBtn:SetText(MTH_OPT_L("COMMON_CLOSE_SHORT", "X"))
closeBtn:SetScript("OnClick", function() MetaHuntOptions:Hide() end)
closeBtn:SetScript("OnClick", function() MTH_OPT_AnimateClose() end)
end
MTH_BuildOptionsTree()
+9
View File
@@ -403,6 +403,7 @@ local lnl = {
expiresAt = 0,
DURATION = 10, -- Lock and Load real duration (tooltip: "Lasts 10 sec or until Aimed Shot is cast")
}
local MTH_EA_LnLWasActive = false -- for detecting the proc rising edge (animations)
-- ── Confirmed icon paths (captured in-game 2026-03-21) ────────
-- Action-button spells (spellbook scan)
@@ -700,10 +701,18 @@ MTH_EA_UpdateUI = function()
cellTop.icon:SetVertexColor(1.00, 0.82, 0.00, 1)
cellTop:SetBackdropBorderColor(1.00, 0.82, 0.00, 1)
cellTopCD:SetText("|cffffffff" .. secs .. "|r")
if not MTH_EA_LnLWasActive then
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function"
and MTH_FX_IsEnabled("combat.mmprocs") then
MTH_FX_Flash(cellTop, 1.00, 0.82, 0.20, 0.55)
end
MTH_EA_LnLWasActive = true
end
else
cellTop.icon:SetVertexColor(0.28, 0.28, 0.28, 0.40)
cellTop:SetBackdropBorderColor(0.25, 0.25, 0.25, 0.35)
cellTopCD:SetText("")
MTH_EA_LnLWasActive = false
end
end
+15
View File
@@ -221,6 +221,14 @@ local function MTHSmartAmmo_ShowFallbackWarning(previousAmmo, newAmmo)
elseif UIErrorsFrame and UIErrorsFrame.AddMessage then
UIErrorsFrame:AddMessage(warning, 1.0, 0.15, 0.15, 1.0)
end
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function"
and MTH_FX_IsEnabled("combat.ammoswap") then
local target = getglobal("zButtonAmmo")
if target then
MTH_FX_Flash(target, 1.00, 0.75, 0.20, 0.5)
end
end
end
local MTHSmartAmmo_FallbackCheckFrame = nil
@@ -371,6 +379,13 @@ local function MTHSmartAmmo_HandleWeaponSwapAutoEquip(reason)
if MTHSmartAmmo_EquipAmmoFromSlot(bestAmmo.bag, bestAmmo.slot) then
MTH_SA_LastKnownEquippedName = bestAmmo.name
MTHSmartAmmo_RefreshAmmoButtonDisplay()
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function"
and MTH_FX_IsEnabled("combat.rangedswap") then
local target = getglobal("zButtonAmmo")
if target then
MTH_FX_Flash(target, 0.30, 0.70, 1.00, 0.5)
end
end
end
end
+23
View File
@@ -5,6 +5,8 @@
local ZBAR_FRAME_NAME = "MTH_ZBar_Anchor"
local ZBar_Sauce = PizzaSauce
local ZBAR_ALL_BUTTONS = {
"zButtonAspect",
"zButtonAmmo",
@@ -282,6 +284,26 @@ function MTH_ZBar_Release()
end
end
-- Animations: gentle staggered fade-in of the bar's buttons when it activates.
function MTH_ZBar_AnimateActivate()
if not ZBar_Sauce then return end
if type(MTH_FX_IsEnabled) ~= "function" or not MTH_FX_IsEnabled("ui.zbar") then
return
end
local s = MTH_ZBar_GetSaved()
local order = s.order or {}
for i = 1, table.getn(order) do
local buttonName = order[i]
if type(buttonName) == "string" then
local btn = getglobal(buttonName)
if btn and btn:IsShown() then
btn:SetAlpha(0)
ZBar_Sauce:FadeTo(btn, 1, 0.30, "outQuad", { delay = (i - 1) * 0.05 })
end
end
end
end
-- Called when the user toggles the Enable checkbox in the options.
function MTH_ZBar_SetEnabled(enabled)
local s = MTH_ZBar_GetSaved()
@@ -289,6 +311,7 @@ function MTH_ZBar_SetEnabled(enabled)
if enabled then
MTH_ZBar_EnsureAnchor()
MTH_ZBar_ApplyLayout()
MTH_ZBar_AnimateActivate()
else
MTH_ZBar_Release()
end
+28
View File
@@ -312,6 +312,8 @@ local function zButtonPet_GetCorePetInfo()
return nil
end
local zButtonPet_LastLoyalty = nil
local function zButtonPet_RefreshSavedPetState(saved, corePetInfo)
local hasLivePet = false
if type(UnitExists) == "function" then
@@ -343,8 +345,34 @@ local function zButtonPet_RefreshSavedPetState(saved, corePetInfo)
if happiness == nil and type(GetPetHappiness) == "function" then
happiness = GetPetHappiness()
end
local prevHappiness = saved["pet"]["happiness"]
saved["pet"]["happiness"] = happiness
-- Animations: flash the pet button when happiness or loyalty changes.
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function" then
if MTH_FX_IsEnabled("pet.happiness")
and prevHappiness ~= nil and happiness ~= nil and happiness ~= prevHappiness then
local target = getglobal("zButtonPet")
if target then
if happiness > prevHappiness then
MTH_FX_Flash(target, 0.30, 1.00, 0.35, 0.5)
else
MTH_FX_Flash(target, 1.00, 0.30, 0.30, 0.5)
end
end
end
local loyalty = corePetInfo and tonumber(corePetInfo.loyaltyLevel) or nil
if MTH_FX_IsEnabled("pet.loyaltyup") and loyalty ~= nil then
if zButtonPet_LastLoyalty ~= nil and loyalty > zButtonPet_LastLoyalty then
local target = getglobal("zButtonPet")
if target then
MTH_FX_Flash(target, 1.00, 0.82, 0.20, 0.6)
end
end
zButtonPet_LastLoyalty = loyalty
end
end
if isDead then
saved["pet"]["status"] = 1
elseif currentHealth and currentHealthMax and currentHealthMax > 0 then