mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-10-08 17:50:00 +00:00
zAmmo low-ammo flash + usage tracker; zPet unhappy flash; split parent/child tooltips
This commit is contained in:
@@ -797,7 +797,11 @@ function ZSpellButtonParent_OnEnter(frame)
|
||||
ZSpellButton_SetChildrenExpanded(frame, true)
|
||||
end
|
||||
ZSpellButton_ResetFadeTimer(frame)
|
||||
if frame.tooltip and frame.id then
|
||||
local showParentTooltip = frame.parentTooltip
|
||||
if showParentTooltip == nil then
|
||||
showParentTooltip = frame.tooltip
|
||||
end
|
||||
if showParentTooltip and frame.id then
|
||||
GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT")
|
||||
local msg, rank
|
||||
|
||||
@@ -807,6 +811,9 @@ function ZSpellButtonParent_OnEnter(frame)
|
||||
msg = msg.." ("..rank..")"
|
||||
end
|
||||
GameTooltip:SetText(msg, 1, 1, 1)
|
||||
elseif frame.suppressItemTooltip then
|
||||
GameTooltip:ClearLines()
|
||||
GameTooltip:SetText(frame.ammoname or frame.ammolink or "Ammo", 1, 1, 1)
|
||||
else
|
||||
local showedItemTooltip = nil
|
||||
if frame.ammobag and frame.ammoslot and type(GameTooltip.SetBagItem) == "function" then
|
||||
@@ -838,6 +845,10 @@ function ZSpellButtonParent_OnEnter(frame)
|
||||
end
|
||||
end
|
||||
|
||||
if type(frame.extraTooltip) == "function" then
|
||||
frame.extraTooltip(GameTooltip)
|
||||
end
|
||||
|
||||
GameTooltip:AddLine("Alt+Drag To Move This Button")
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
@@ -22,6 +22,8 @@ if not root["zButtonAmmo"] then
|
||||
root["zButtonAmmo"]["children"]["hideonclick"] = 1
|
||||
root["zButtonAmmo"]["showammoname"] = 1
|
||||
root["zButtonAmmo"]["showtotalperc"] = 1
|
||||
root["zButtonAmmo"]["lowflash"] = 1
|
||||
root["zButtonAmmo"]["parenttooltip"] = 1
|
||||
root["zButtonAmmo"]["lastEquipped"] = nil
|
||||
end
|
||||
|
||||
@@ -521,6 +523,139 @@ local function zButtonAmmo_GetCountDivisor(category)
|
||||
return 2000
|
||||
end
|
||||
|
||||
-- Reset-based ammo usage tracker (reliable, retrospective — no prediction).
|
||||
-- session (consumed total + per-name breakdown + resetAt) persists in saved;
|
||||
-- the baseline tables are runtime only.
|
||||
local zButtonAmmo_LastByName = nil
|
||||
local zButtonAmmo_LastCategory = nil
|
||||
local zButtonAmmo_SettleUntil = 0
|
||||
|
||||
local function zButtonAmmo_EnsureSession()
|
||||
local saved = zButtonAmmo_GetSaved()
|
||||
if type(saved["session"]) ~= "table" then
|
||||
saved["session"] = {}
|
||||
end
|
||||
local session = saved["session"]
|
||||
if tonumber(session["consumed"]) == nil then
|
||||
session["consumed"] = 0
|
||||
end
|
||||
if type(session["byName"]) ~= "table" then
|
||||
session["byName"] = {}
|
||||
end
|
||||
if tonumber(session["resetAt"]) == nil then
|
||||
session["resetAt"] = (time and time()) or 0
|
||||
end
|
||||
return session
|
||||
end
|
||||
|
||||
function zButtonAmmo_ResetSession()
|
||||
local session = zButtonAmmo_EnsureSession()
|
||||
session["consumed"] = 0
|
||||
session["byName"] = {}
|
||||
session["resetAt"] = (time and time()) or 0
|
||||
zButtonAmmo_LastByName = nil
|
||||
zButtonAmmo_LastCategory = nil
|
||||
if MTH and MTH.Print then
|
||||
MTH:Print("Ammo usage counter reset.")
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonAmmo_CurrentCountsByName(category)
|
||||
local counts = {}
|
||||
for name, info in pairs(zButtonAmmo_Cache) do
|
||||
if info and info.type == category then
|
||||
counts[name] = (tonumber(info.count) or 0)
|
||||
end
|
||||
end
|
||||
return counts
|
||||
end
|
||||
|
||||
local function zButtonAmmo_SampleConsumption()
|
||||
local category = zButtonAmmo_GetEquippedAmmoCategory()
|
||||
if not category then
|
||||
zButtonAmmo_LastByName = nil
|
||||
zButtonAmmo_LastCategory = nil
|
||||
return
|
||||
end
|
||||
local current = zButtonAmmo_CurrentCountsByName(category)
|
||||
local now = GetTime and GetTime() or 0
|
||||
local last = zButtonAmmo_LastByName
|
||||
local categoryChanged = (category ~= zButtonAmmo_LastCategory)
|
||||
zButtonAmmo_LastCategory = category
|
||||
-- Baseline-only during the post-load settle window, on weapon/category
|
||||
-- swaps, and on the first sample — these are not real shots.
|
||||
if now < (zButtonAmmo_SettleUntil or 0) or categoryChanged or last == nil then
|
||||
zButtonAmmo_LastByName = current
|
||||
return
|
||||
end
|
||||
local session = zButtonAmmo_EnsureSession()
|
||||
for name, lastCount in pairs(last) do
|
||||
local cur = current[name] or 0
|
||||
if cur < lastCount then
|
||||
local delta = lastCount - cur
|
||||
session["consumed"] = (tonumber(session["consumed"]) or 0) + delta
|
||||
session["byName"][name] = (tonumber(session["byName"][name]) or 0) + delta
|
||||
end
|
||||
end
|
||||
zButtonAmmo_LastByName = current
|
||||
end
|
||||
|
||||
local function zButtonAmmo_FormatElapsed(seconds)
|
||||
if seconds < 0 then seconds = 0 end
|
||||
local mins = math.floor(seconds / 60)
|
||||
local hrs = math.floor(mins / 60)
|
||||
if hrs > 0 then
|
||||
return hrs .. "h " .. (mins - hrs * 60) .. "m"
|
||||
elseif mins > 0 then
|
||||
return mins .. "m"
|
||||
end
|
||||
return math.floor(seconds) .. "s"
|
||||
end
|
||||
|
||||
function zButtonAmmo_AppendSessionReport(tooltip)
|
||||
if not (tooltip and tooltip.AddLine) then
|
||||
return
|
||||
end
|
||||
local category = zButtonAmmo_GetEquippedAmmoCategory()
|
||||
if category then
|
||||
local total = zButtonAmmo_GetTotalAmmoCount(category)
|
||||
tooltip:AddLine("In bags: " .. total .. " " .. (category == "Bullet" and "bullets" or "arrows"), 0.8, 0.8, 0.8)
|
||||
end
|
||||
local session = zButtonAmmo_EnsureSession()
|
||||
local used = tonumber(session["consumed"]) or 0
|
||||
local elapsed = ((time and time()) or 0) - (tonumber(session["resetAt"]) or 0)
|
||||
if elapsed < 0 then elapsed = 0 end
|
||||
tooltip:AddLine("Used since reset: " .. used .. " (" .. zButtonAmmo_FormatElapsed(elapsed) .. ")", 1, 0.82, 0)
|
||||
if used > 0 and elapsed >= 60 then
|
||||
tooltip:AddLine(string.format("Avg: ~%.1f /min", used / (elapsed / 60)), 0.7, 0.7, 0.7)
|
||||
end
|
||||
local byName = session["byName"]
|
||||
if type(byName) == "table" and used > 0 then
|
||||
local rows = {}
|
||||
for name, cnt in pairs(byName) do
|
||||
if (tonumber(cnt) or 0) > 0 then
|
||||
table.insert(rows, { name = name, count = tonumber(cnt) or 0 })
|
||||
end
|
||||
end
|
||||
if table.getn(rows) > 0 then
|
||||
table.sort(rows, function(a, b) return a.count > b.count end)
|
||||
tooltip:AddLine(" ")
|
||||
tooltip:AddLine("Breakdown:", 0.9, 0.9, 0.9)
|
||||
for i = 1, table.getn(rows) do
|
||||
local row = rows[i]
|
||||
local frac = row.count / used
|
||||
local right = row.count .. " " .. math.floor(frac * 100 + 0.5) .. "%"
|
||||
if type(tooltip.AddDoubleLine) == "function" then
|
||||
tooltip:AddDoubleLine(row.name, right, 1, 1, 1, 0.6, 0.8, 1)
|
||||
else
|
||||
tooltip:AddLine(row.name .. ": " .. right, 1, 1, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
tooltip:AddLine("Left-click: reset counter", 0.5, 0.5, 0.5)
|
||||
end
|
||||
|
||||
local function zButtonAmmo_UpdateTotalPercent(button)
|
||||
local totalText = zButtonAmmo_EnsureTotalPercentText(button)
|
||||
if not totalText then
|
||||
@@ -610,6 +745,86 @@ local function zButtonAmmo_ShouldShowTotalCount()
|
||||
return saved["counttotal"] and true or false
|
||||
end
|
||||
|
||||
local function zButtonAmmo_ShouldLowFlash()
|
||||
local saved = zButtonAmmo_GetSaved()
|
||||
return saved["lowflash"] and true or false
|
||||
end
|
||||
|
||||
-- Low-ammo threshold mirrors SmartAmmo's when available.
|
||||
local function zButtonAmmo_GetLowThreshold()
|
||||
if type(MTHSmartAmmo_GetLowAmmoThreshold) == "function" then
|
||||
local t = tonumber(MTHSmartAmmo_GetLowAmmoThreshold())
|
||||
if t and t > 0 then
|
||||
return t
|
||||
end
|
||||
end
|
||||
return 200
|
||||
end
|
||||
|
||||
local function zButtonAmmo_EnsureLowFlash(button)
|
||||
if not button then
|
||||
return nil
|
||||
end
|
||||
if button.ammoLowFlash then
|
||||
return button.ammoLowFlash
|
||||
end
|
||||
local tex = button:CreateTexture(nil, "OVERLAY")
|
||||
tex:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
|
||||
tex:SetBlendMode("ADD")
|
||||
tex:SetVertexColor(1, 0.12, 0.12)
|
||||
tex:SetPoint("CENTER", button, "CENTER", 0, 0)
|
||||
tex:SetWidth((button:GetWidth() or 36) * 1.6)
|
||||
tex:SetHeight((button:GetHeight() or 36) * 1.6)
|
||||
tex:Hide()
|
||||
button.ammoLowFlash = tex
|
||||
return tex
|
||||
end
|
||||
|
||||
local MTH_ZH_AmmoLowFlashDriver
|
||||
local zButtonAmmo_LowFlashElapsed = 0
|
||||
|
||||
local function zButtonAmmo_LowFlashOnUpdate()
|
||||
if not (zButtonAmmo and zButtonAmmo.ammoLowFlash and zButtonAmmo.ammoLowFlash:IsShown()) then
|
||||
return
|
||||
end
|
||||
zButtonAmmo_LowFlashElapsed = zButtonAmmo_LowFlashElapsed + (arg1 or 0)
|
||||
zButtonAmmo.ammoLowFlash:SetAlpha(0.45 + 0.4 * math.sin(zButtonAmmo_LowFlashElapsed * 4))
|
||||
end
|
||||
|
||||
local function zButtonAmmo_SetLowFlashRunning(running)
|
||||
if running and not MTH_ZH_AmmoLowFlashDriver then
|
||||
MTH_ZH_AmmoLowFlashDriver = CreateFrame("Frame", "MTH_ZH_AmmoLowFlashDriver")
|
||||
end
|
||||
if not MTH_ZH_AmmoLowFlashDriver then
|
||||
return
|
||||
end
|
||||
MTH_ZH_AmmoLowFlashDriver:SetScript("OnUpdate", running and zButtonAmmo_LowFlashOnUpdate or nil)
|
||||
end
|
||||
|
||||
local function zButtonAmmo_UpdateLowFlash(button)
|
||||
local tex = zButtonAmmo_EnsureLowFlash(button)
|
||||
if not tex then
|
||||
return
|
||||
end
|
||||
local low = false
|
||||
if zButtonAmmo_ShouldLowFlash() then
|
||||
local category = zButtonAmmo_GetEquippedAmmoCategory()
|
||||
if category then
|
||||
local total = zButtonAmmo_GetTotalAmmoCount(category)
|
||||
if total < zButtonAmmo_GetLowThreshold() then
|
||||
low = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if low then
|
||||
tex:Show()
|
||||
zButtonAmmo_SetLowFlashRunning(true)
|
||||
else
|
||||
tex:Hide()
|
||||
zButtonAmmo_SetLowFlashRunning(false)
|
||||
end
|
||||
end
|
||||
|
||||
function zButtonAmmo_UpdateButton(button)
|
||||
if not button then
|
||||
button = this
|
||||
@@ -632,6 +847,10 @@ function zButtonAmmo_UpdateButton(button)
|
||||
if button == zButtonAmmo and button.ammoTotalGauge then
|
||||
button.ammoTotalGauge:Hide()
|
||||
end
|
||||
if button == zButtonAmmo and button.ammoLowFlash then
|
||||
button.ammoLowFlash:Hide()
|
||||
zButtonAmmo_SetLowFlashRunning(false)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@@ -683,6 +902,7 @@ function zButtonAmmo_UpdateButton(button)
|
||||
end
|
||||
zButtonAmmo_UpdateTotalPercent(button)
|
||||
zButtonAmmo_UpdateTotalGauge(button)
|
||||
zButtonAmmo_UpdateLowFlash(button)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -843,6 +1063,12 @@ local function zButtonAmmo_EnsureSpellOrder(ammoList)
|
||||
if saved["showtotalperc"] == nil then
|
||||
saved["showtotalperc"] = 1
|
||||
end
|
||||
if saved["lowflash"] == nil then
|
||||
saved["lowflash"] = 1
|
||||
end
|
||||
if saved["parenttooltip"] == nil then
|
||||
saved["parenttooltip"] = 1
|
||||
end
|
||||
if not saved["parent"] then
|
||||
saved["parent"] = {}
|
||||
end
|
||||
@@ -887,6 +1113,7 @@ local function zButtonAmmo_ApplyRuntimeSettings()
|
||||
end
|
||||
local saved = zButtonAmmo_GetSaved()
|
||||
zButtonAmmo.tooltip = saved["tooltip"] and true or false
|
||||
zButtonAmmo.parentTooltip = saved["parenttooltip"] and true or false
|
||||
zButtonAmmo.hideonclick = saved["children"] and saved["children"]["hideonclick"] and true or false
|
||||
zButtonAmmo.expandonhover = saved["children"] and saved["children"]["expandonhover"] and true or false
|
||||
zButtonAmmo.fadetimer = saved["children"] and tonumber(saved["children"]["fadetimer"]) or 0
|
||||
@@ -1013,6 +1240,16 @@ function zButtonAmmo_OnEvent()
|
||||
end
|
||||
zButtonAmmo.customSetButtons = zButtonAmmo_SetButtons
|
||||
zButtonAmmo.customUpdateButton = zButtonAmmo_UpdateButton
|
||||
zButtonAmmo.extraTooltip = zButtonAmmo_AppendSessionReport
|
||||
zButtonAmmo.suppressItemTooltip = true
|
||||
zButtonAmmo.beforeclick = function(btn)
|
||||
if btn ~= zButtonAmmo then
|
||||
return false
|
||||
end
|
||||
zButtonAmmo_ResetSession()
|
||||
return true
|
||||
end
|
||||
zButtonAmmo_SettleUntil = (GetTime and GetTime() or 0) + 5
|
||||
zButtonAmmo_CreateButtons()
|
||||
MTH_ZH_AmmoAdjust = CreateFrame("Frame", "MTH_ZH_AmmoAdjust")
|
||||
MTH_ZH_AmmoAdjust:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
@@ -1137,6 +1374,8 @@ function zButtonAmmo_Reset()
|
||||
saved["children"]["hideonclick"] = 1
|
||||
saved["showammoname"] = 1
|
||||
saved["showtotalperc"] = 1
|
||||
saved["lowflash"] = 1
|
||||
saved["parenttooltip"] = 1
|
||||
saved["lastEquipped"] = nil
|
||||
end
|
||||
|
||||
@@ -1215,6 +1454,7 @@ function MTH_ZH_AmmoAdjust_OnEvent()
|
||||
local listChanged = (ZHunterMod_Ammo_Buttons ~= ammoList)
|
||||
ZHunterMod_Ammo_Buttons = ammoList
|
||||
zButtonAmmo_RebuildCache()
|
||||
zButtonAmmo_SampleConsumption()
|
||||
local cacheSignature = zButtonAmmo_GetCacheSignature(ammoList)
|
||||
local rebuiltButtons = false
|
||||
if listChanged or cacheSignature ~= zButtonAmmo_LastCacheSignature then
|
||||
|
||||
@@ -57,6 +57,68 @@ local function zButtonPet_GetSaved()
|
||||
return currentRoot["zButtonPet"]
|
||||
end
|
||||
|
||||
-- Persistent "feed me" nudge: pulse the zPet parent while the pet is Unhappy.
|
||||
local MTH_ZH_PetHappyFlashDriver
|
||||
local zButtonPet_HappyFlashElapsed = 0
|
||||
|
||||
local function zButtonPet_EnsureHappyFlash()
|
||||
local button = getglobal("zButtonPet")
|
||||
if not button then
|
||||
return nil
|
||||
end
|
||||
if button.petHappyFlash then
|
||||
return button.petHappyFlash
|
||||
end
|
||||
local tex = button:CreateTexture(nil, "OVERLAY")
|
||||
tex:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
|
||||
tex:SetBlendMode("ADD")
|
||||
tex:SetVertexColor(1, 0.15, 0.15)
|
||||
tex:SetPoint("CENTER", button, "CENTER", 0, 0)
|
||||
tex:SetWidth((button:GetWidth() or 36) * 1.6)
|
||||
tex:SetHeight((button:GetHeight() or 36) * 1.6)
|
||||
tex:Hide()
|
||||
button.petHappyFlash = tex
|
||||
return tex
|
||||
end
|
||||
|
||||
local function zButtonPet_HappyFlashOnUpdate()
|
||||
local button = getglobal("zButtonPet")
|
||||
if not (button and button.petHappyFlash and button.petHappyFlash:IsShown()) then
|
||||
return
|
||||
end
|
||||
zButtonPet_HappyFlashElapsed = zButtonPet_HappyFlashElapsed + (arg1 or 0)
|
||||
button.petHappyFlash:SetAlpha(0.4 + 0.4 * math.sin(zButtonPet_HappyFlashElapsed * 3))
|
||||
end
|
||||
|
||||
local function zButtonPet_SetHappyFlashRunning(running)
|
||||
if running and not MTH_ZH_PetHappyFlashDriver then
|
||||
MTH_ZH_PetHappyFlashDriver = CreateFrame("Frame", "MTH_ZH_PetHappyFlashDriver")
|
||||
end
|
||||
if not MTH_ZH_PetHappyFlashDriver then
|
||||
return
|
||||
end
|
||||
MTH_ZH_PetHappyFlashDriver:SetScript("OnUpdate", running and zButtonPet_HappyFlashOnUpdate or nil)
|
||||
end
|
||||
|
||||
local function zButtonPet_UpdateHappyFlash(happiness)
|
||||
local tex = zButtonPet_EnsureHappyFlash()
|
||||
if not tex then
|
||||
return
|
||||
end
|
||||
local saved = zButtonPet_GetSaved()
|
||||
local enabled = saved["unhappyflash"]
|
||||
if enabled == nil then
|
||||
enabled = 1
|
||||
end
|
||||
if enabled and happiness ~= nil and tonumber(happiness) == 1 then
|
||||
tex:Show()
|
||||
zButtonPet_SetHappyFlashRunning(true)
|
||||
else
|
||||
tex:Hide()
|
||||
zButtonPet_SetHappyFlashRunning(false)
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonPet_EnsureConfig()
|
||||
local saved = zButtonPet_GetSaved()
|
||||
saved["count"] = nil
|
||||
@@ -131,6 +193,9 @@ local function zButtonPet_EnsureConfig()
|
||||
saved["visible"][i] = 1
|
||||
end
|
||||
end
|
||||
if saved["unhappyflash"] == nil then
|
||||
saved["unhappyflash"] = 1
|
||||
end
|
||||
end
|
||||
|
||||
local function zButtonPet_ApplyRuntimeSettings()
|
||||
@@ -347,6 +412,7 @@ local function zButtonPet_RefreshSavedPetState(saved, corePetInfo)
|
||||
end
|
||||
local prevHappiness = saved["pet"]["happiness"]
|
||||
saved["pet"]["happiness"] = happiness
|
||||
zButtonPet_UpdateHappyFlash(happiness)
|
||||
|
||||
-- Animations: flash the pet button when happiness or loyalty changes.
|
||||
if type(MTH_FX_Flash) == "function" and type(MTH_FX_IsEnabled) == "function" then
|
||||
|
||||
Reference in New Issue
Block a user