zAmmo: total ammo meter (centered % + side gauge) with options

This commit is contained in:
DuvelCorp
2026-10-04 20:37:54 +02:00
parent bb5c875835
commit f6b495d68d
3 changed files with 208 additions and 0 deletions
+2
View File
@@ -11,6 +11,8 @@ All notable changes to MetaHunt will be documented in this file.
- **zTrap — trap cooldown**: The zTrap buttons now show the trap re-arm cooldown (the ~15s before you can lay another trap) as a cooldown spiral plus a seconds countdown, on both the parent and child buttons. A new "Show cooldown" toggle lives in Options → zButtons → zTrap (on by default).
- **zAmmo — total ammo meter**: The zAmmo parent button can now show how stocked you are on your equipped weapon's ammo, as a percentage of your quiver/pouch capacity (all matching arrows or bullets across your bags ÷ total quiver/pouch slots × 200). Two heat-coloured display styles (red when low → green when full) are available as toggles in Options → zButtons → zAmmo → Parent Button: a **centered %** on the button, and a **vertical gauge** beside it (which flips to the side opposite the children's expand direction).
### Fixed
- **Feed-O-Matic — feeding food that's too low level**: With nearly-full bags, FeedOMatic could keep trying to feed a small stack whose level was too low for your pet, which the server refuses ("That food's level is not high enough"). It now skips below-minimum-level foods and only offers food the pet can actually eat.
+30
View File
@@ -301,6 +301,14 @@ local function MTH_ZB_EnsureButtonOptionDefaults(buttonName)
saved["showammoname"] = true
end
saved["showammoname"] = saved["showammoname"] and true or false
if saved["showtotalperc"] == nil then
saved["showtotalperc"] = true
end
saved["showtotalperc"] = saved["showtotalperc"] and true or false
if saved["showtotalgauge"] == nil then
saved["showtotalgauge"] = false
end
saved["showtotalgauge"] = saved["showtotalgauge"] and true or false
end
if buttonName == "zButtonTrap" then
@@ -596,6 +604,28 @@ local function MTH_SetupButtonOptions(containerName, buttonName, displayName, ma
end
end,
})
parentBox:Checkbox(containerName.."ShowTotalPercent", MTH_ZB_L("ZB_LABEL_SHOW_TOTAL_PERCENT", "Show total % (center)"), {
checked = saved["showtotalperc"],
onClick = function()
if not this then return end
local checked = this:GetChecked() == 1
ZHunterMod_Saved[buttonName]["showtotalperc"] = checked
if buttonObj and buttonObj.ammoname and not buttonObj.isspell then
zButtonAmmo_UpdateButton(buttonObj)
end
end,
})
parentBox:Checkbox(containerName.."ShowTotalGauge", MTH_ZB_L("ZB_LABEL_SHOW_TOTAL_GAUGE", "Show total gauge (side)"), {
checked = saved["showtotalgauge"],
onClick = function()
if not this then return end
local checked = this:GetChecked() == 1
ZHunterMod_Saved[buttonName]["showtotalgauge"] = checked
if buttonObj and buttonObj.ammoname and not buttonObj.isspell then
zButtonAmmo_UpdateButton(buttonObj)
end
end,
})
end
MTH_SetButtonEnabledState(buttonName, buttonObj, saved["enabled"] and true or false)
+176
View File
@@ -21,6 +21,7 @@ if not root["zButtonAmmo"] then
root["zButtonAmmo"]["children"]["size"] = 36
root["zButtonAmmo"]["children"]["hideonclick"] = 1
root["zButtonAmmo"]["showammoname"] = 1
root["zButtonAmmo"]["showtotalperc"] = 1
root["zButtonAmmo"]["lastEquipped"] = nil
end
@@ -431,6 +432,167 @@ local function zButtonAmmo_GetEquippedAmmoInfo()
}
end
local function zButtonAmmo_EnsureTotalPercentText(button)
if button and not button.ammoTotalPercentText then
button.ammoTotalPercentText = button:CreateFontString(nil, "OVERLAY")
button.ammoTotalPercentText:SetPoint("CENTER", button, "CENTER", 0, 0)
button.ammoTotalPercentText:SetFont("Fonts\\ARIALN.ttf", 13, "THICKOUTLINE")
end
return button and button.ammoTotalPercentText
end
local function zButtonAmmo_ShouldShowTotalPercent()
local saved = zButtonAmmo_GetSaved()
return saved["showtotalperc"] and true or false
end
-- "Arrow" or "Bullet" for the currently equipped ranged weapon, or nil if none.
local function zButtonAmmo_GetEquippedAmmoCategory()
if not (GetInventoryItemLink and GetItemInfo) then
return nil
end
local link = GetInventoryItemLink("player", 18)
if not link then
return nil
end
local _, _, id = string.find(link, "Hitem:((%d+).-)")
if not id then
return nil
end
local _, _, _, _, _, weaponType = GetItemInfo(id)
if weaponType == MTH_WEAPON_GUNS then
return "Bullet"
elseif weaponType == MTH_WEAPON_BOWS or weaponType == MTH_WEAPON_CROSSBOWS then
return "Arrow"
end
return nil
end
-- Capacity = total slots of every equipped quiver (arrows) or ammo pouch
-- (bullets) multiplied by the per-slot stack size.
local zButtonAmmo_StackSize = 200
local function zButtonAmmo_GetAmmoCapacity(category)
if not category then
return 0
end
local wantedSubtype = (category == "Bullet") and "Ammo Pouch" or "Quiver"
local totalSlots = 0
for bag = 1, 4 do
local invSlot = ContainerIDToInventoryID and ContainerIDToInventoryID(bag) or nil
if invSlot then
local link = GetInventoryItemLink and GetInventoryItemLink("player", invSlot)
if link then
local _, _, id = string.find(link, "Hitem:((%d+).-)")
if id then
local _, _, _, _, _, bagSubtype = GetItemInfo(id)
if bagSubtype == wantedSubtype then
totalSlots = totalSlots + (GetContainerNumSlots(bag) or 0)
end
end
end
end
end
return totalSlots * zButtonAmmo_StackSize
end
-- Sum of all matching ammo across every bag, from the live cache.
local function zButtonAmmo_GetTotalAmmoCount(category)
if not category then
return 0
end
local total = 0
for _, info in pairs(zButtonAmmo_Cache) do
if info and info.type == category then
total = total + (tonumber(info.count) or 0)
end
end
return total
end
local function zButtonAmmo_UpdateTotalPercent(button)
local totalText = zButtonAmmo_EnsureTotalPercentText(button)
if not totalText then
return
end
if not zButtonAmmo_ShouldShowTotalPercent() then
totalText:SetText("")
return
end
local category = zButtonAmmo_GetEquippedAmmoCategory()
local capacity = zButtonAmmo_GetAmmoCapacity(category)
if not category or capacity <= 0 then
totalText:SetText("")
return
end
local perc = zButtonAmmo_GetTotalAmmoCount(category) / capacity
local r, g, b = zButtonAmmo_GetColorGradient(perc)
totalText:SetTextColor(r, g, b, 1)
totalText:SetText(math.floor(perc * 100 + 0.5) .. "%")
end
local function zButtonAmmo_ShouldShowTotalGauge()
local saved = zButtonAmmo_GetSaved()
return saved["showtotalgauge"] and true or false
end
local function zButtonAmmo_EnsureTotalGauge(button)
if not button then
return nil
end
if button.ammoTotalGauge then
return button.ammoTotalGauge
end
local gauge = CreateFrame("Frame", nil, button)
gauge:SetWidth(7)
gauge:SetHeight(button:GetHeight() or 36)
local bg = gauge:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints(gauge)
bg:SetTexture(0, 0, 0, 0.55)
local bar = CreateFrame("StatusBar", nil, gauge)
bar:SetAllPoints(gauge)
bar:SetOrientation("VERTICAL")
bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
bar:SetMinMaxValues(0, 1)
bar:SetValue(0)
gauge.bar = bar
button.ammoTotalGauge = gauge
return gauge
end
local function zButtonAmmo_UpdateTotalGauge(button)
local gauge = zButtonAmmo_EnsureTotalGauge(button)
if not gauge then
return
end
if not zButtonAmmo_ShouldShowTotalGauge() then
gauge:Hide()
return
end
local category = zButtonAmmo_GetEquippedAmmoCategory()
local capacity = zButtonAmmo_GetAmmoCapacity(category)
if not category or capacity <= 0 then
gauge:Hide()
return
end
local perc = zButtonAmmo_GetTotalAmmoCount(category) / capacity
local fill = perc
if fill > 1 then fill = 1 end
if fill < 0 then fill = 0 end
gauge:SetHeight(button:GetHeight() or 36)
gauge:ClearAllPoints()
-- Gauge sits opposite the child expand direction.
local saved = zButtonAmmo_GetSaved()
if saved["firstbutton"] == "LEFT" then
gauge:SetPoint("LEFT", button, "RIGHT", 2, 0)
else
gauge:SetPoint("RIGHT", button, "LEFT", -2, 0)
end
gauge.bar:SetValue(fill)
local r, g, b = zButtonAmmo_GetColorGradient(perc)
gauge.bar:SetStatusBarColor(r, g, b)
gauge:Show()
end
function zButtonAmmo_UpdateButton(button)
if not button then
button = this
@@ -447,6 +609,12 @@ function zButtonAmmo_UpdateButton(button)
if button.ammoShortLabelText then
button.ammoShortLabelText:SetText("")
end
if button == zButtonAmmo and button.ammoTotalPercentText then
button.ammoTotalPercentText:SetText("")
end
if button == zButtonAmmo and button.ammoTotalGauge then
button.ammoTotalGauge:Hide()
end
return
end
@@ -484,6 +652,10 @@ function zButtonAmmo_UpdateButton(button)
countText:SetText("Out!")
end
end
if button == zButtonAmmo then
zButtonAmmo_UpdateTotalPercent(button)
zButtonAmmo_UpdateTotalGauge(button)
end
end
function zButtonAmmo_SetButtons(parent, ammoList)
@@ -640,6 +812,9 @@ local function zButtonAmmo_EnsureSpellOrder(ammoList)
if saved["showammoname"] == nil then
saved["showammoname"] = 1
end
if saved["showtotalperc"] == nil then
saved["showtotalperc"] = 1
end
if not saved["parent"] then
saved["parent"] = {}
end
@@ -933,6 +1108,7 @@ function zButtonAmmo_Reset()
saved["children"]["size"] = 36
saved["children"]["hideonclick"] = 1
saved["showammoname"] = 1
saved["showtotalperc"] = 1
saved["lastEquipped"] = nil
end