mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-22 07:36:58 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 680ddcba8a | |||
| 8d80d0663c |
+25
-3
@@ -2,17 +2,39 @@
|
||||
|
||||
All notable changes to MetaHunt will be documented in this file.
|
||||
|
||||
## [1.4.1] - 2026-03-24
|
||||
|
||||
### Added
|
||||
|
||||
- **zTrack**: added `Find Trees` in tracking spells.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Performance — MM Widget / ExpAmmo**: Replaced tooltip-based aura scanning (which triggered hidden tooltip rendering on every aura check) with direct texture/icon comparison via `UnitBuff`/`UnitDebuff`. Added a 150 ms throttle on `PLAYER_AURAS_CHANGED`, which fires 10–50+ times per second in combat. Lock and Load detection and ammo cycle recovery after `/reload` both updated to use the new zero-cost texture path.
|
||||
|
||||
- **Performance — event frame leaks**: Some addon features were registering WoW game events at load time and never unregistering them when the feature was disabled from the options, causing their `OnEvent` handlers to fire even with the option turned off. Fixed for: Auto-Strip (`PLAYER_REGEN_*`), Smart Ammo (`SPELLCAST_*`, `START/STOP_AUTOREPEAT_SPELL`), and some zButton frames (Pet, Mounts, Track, Trap, Toys). Events are now properly registered on enable and unregistered on disable.
|
||||
|
||||
- **Chronometer — trap effects from other hunters**: Trap effect bars (`Immolation Trap Effect`, `Explosive Trap Effect`, `Freezing Trap Effect`, `Frost Trap Aura`) were incorrectly appearing when another hunter's trap triggered on a mob you were also targeting. .
|
||||
|
||||
- **Version check broadcast interval**: Increased update notification broadcast cooldown from 10 minutes to 1 hour to reduce channel traffic now that the user base has grown.
|
||||
|
||||
- **Profile snapshot memory**: The auto `BuildSnapshot` (called on every `/reload` via `PLAYER_LOGOUT`) was deep-copying `feedomatic.legacy`, a large migration table mirroring `FOM_Cooking`, `FOM_QuestFood`, `FOM_AddedFoods` etc. These are runtime/operational blobs, not user configuration settings, and should never be included in a profile. Introduced `MTH_Profile_CopyModules` which skips `legacy` and `history` keys, reducing the snapshot allocation from ~1 MB to a few KB.
|
||||
|
||||
|
||||
|
||||
## [1.4.0] - 2026-03-23
|
||||
|
||||
### TWoW 1.18.1 "Nightmares of Ursol" support
|
||||
|
||||
### Added
|
||||
|
||||
- **Complete beast database overhaul**: The MTH beast datastore was reconstructed from scratch, based on a full (beasts) 1.18.1 extract from live DB, gladly provided by Twow staff (thanks @Haaxor!). The beast data should now be 100% accurate, and notably all spawn coordinates, respawn times and pet abilities learnable on all beasts in the world.
|
||||
|
||||
- The **Beast Lore** page of the Book now allows to filter the list by Zone. Additionaly, the beast inspector has been reformated and all meaningful beast's data is displayed nicely.
|
||||
- The **Beast Lore** page of the Book now allows to filter the list by Zone. Additionally, the beast inspector has been reformatted and all meaningful beast's data is displayed nicely.
|
||||
|
||||
- All new and missing **Beasts Models** have been (re)scanned from MPQ game files and are viewable in the Beast Lore page, and browsable in the Family Model viewer.
|
||||
|
||||
- Added **MM widget** module: tracks the new 3-state of Experimental ammo cycle (Fire → Nature → Arcane), the Lock and Load procs, and has adynamic cell that shows either Aimed Shot availability or the right shot to use following the current Experimental ammo proc if any. Lets Make MM great again.
|
||||
- Added **MM widget** module: tracks the new 3-state of Experimental ammo cycle (Fire → Nature → Arcane), the Lock and Load procs, and has a dynamic cell that shows either Aimed Shot availability or the right shot to use following the current Experimental ammo proc if any. Lets Make MM great again.
|
||||
|
||||
- Added new **Moth** pet family.
|
||||
|
||||
@@ -46,7 +68,7 @@ All notable changes to MetaHunt will be documented in this file.
|
||||
### Fixed
|
||||
|
||||
- Fixed **Chronometer** bars appearing from nearby players' combat events (e.g. another hunter's traps or DoTs triggering your own bars).
|
||||
- Fixed the list in Families Book's page, that wasnt tall enough to display all famillies (wolves were hidden).
|
||||
- Fixed the list in Families Book's page, that wasn't tall enough to display all families (wolves were hidden).
|
||||
|
||||
## [1.3.0] - 2026-03-19
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
## Interface: 11200
|
||||
## Version: 1.4.0
|
||||
## Version: 1.4.1
|
||||
## Title: MetaHunt - |cff00ff00Hunter
|
||||
## Author: Metasploit and his Copilot ;)
|
||||
## Notes: Unified addon suite for huntards making old addons compatible with TurtleWoW, and adding an arsenal of never seen Hunter's utilities.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# MetaHunt
|
||||
|
||||
MetaHunt is a Turtle WoW Hunter toolkit.
|
||||
It is a modern modular addon that combines never-seen features, and improves/fixes a few old hunter add-ons.
|
||||
It provides a bunch useful tools for all huntards, wheter they are still levelling, lone-wolf, or HL raider.
|
||||
It is a modern modular addon compiling brand new features, and improving a few old hunter add-ons, that were broken on twow.
|
||||
It provides a bunch of useful tools for all huntards, wheter they are still levelling, lone-wolf, or HL raider.
|
||||
|
||||
## Twow Data
|
||||
|
||||
MetaHunt ships with large up-to-date datastores for all Turtle WOW data a hunter needs :
|
||||
MetaHunt ships with large Turtle WOW datastores :
|
||||
|
||||
- 100% accurate beasts' data, their locations, and the abilities they can learn you
|
||||
- All Pet families, their abilities and their diet
|
||||
@@ -31,7 +31,7 @@ MetaHunt ships with large up-to-date datastores for all Turtle WOW data a hunter
|
||||
- Vendors : Shows if a vendor sells Arrows and/or Bullets.
|
||||
- Your pet : Shows your pet's XP, loyalty, happiness and how much you fed it this session.
|
||||
|
||||
## zBouttons
|
||||
## zButtons
|
||||
|
||||
Old zHunterMod addon on steroids. Fully compatible with Twow, and enhanced with new functionalities
|
||||
|
||||
@@ -63,6 +63,9 @@ 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 mobs involved.
|
||||
|
||||
## Beast model Viewer
|
||||
|
||||
Display the model of all beasts in the world. Always know what you are going to tame exactly before running there ! You can also browse all skin models of the same pet family to find the best-looking pet according to your tastes.
|
||||
|
||||
## The Great Book of Huntards
|
||||
|
||||
|
||||
+18
-6
@@ -150,6 +150,10 @@ function AutoStrip_SetAutoStripToggle(enabled, silent)
|
||||
if enabled then
|
||||
saved["autostrip"] = 1
|
||||
AutoStrip_On = 1
|
||||
if AutoStrip_Frame then
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
end
|
||||
if AutoStripDisplay and AutoStripDisplay:IsVisible() and AutoStripDisplayAutoCast then
|
||||
AutoStripDisplayAutoCast:Show()
|
||||
end
|
||||
@@ -159,6 +163,10 @@ function AutoStrip_SetAutoStripToggle(enabled, silent)
|
||||
else
|
||||
saved["autostrip"] = nil
|
||||
AutoStrip_On = nil
|
||||
if AutoStrip_Frame then
|
||||
AutoStrip_Frame:UnregisterEvent("PLAYER_REGEN_DISABLED")
|
||||
AutoStrip_Frame:UnregisterEvent("PLAYER_REGEN_ENABLED")
|
||||
end
|
||||
if AutoStripDisplayAutoCast then
|
||||
AutoStripDisplayAutoCast:Hide()
|
||||
end
|
||||
@@ -252,10 +260,12 @@ function AutoStrip_UnequipAll(weaponsOnly)
|
||||
end
|
||||
|
||||
local function AutoStrip_OnEvent()
|
||||
AutoStrip_Trace("OnEvent evt=" .. tostring(event or "")
|
||||
.. " runtime=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " wasInCombat=" .. tostring(AutoStrip_WasInCombat and 1 or 0)
|
||||
.. " playerInCombat=" .. tostring((type(UnitAffectingCombat) == "function" and UnitAffectingCombat("player")) and 1 or 0))
|
||||
if AutoStrip_TraceEnabled then
|
||||
AutoStrip_Trace("OnEvent evt=" .. tostring(event or "")
|
||||
.. " runtime=" .. tostring(AutoStrip_On and 1 or 0)
|
||||
.. " wasInCombat=" .. tostring(AutoStrip_WasInCombat and 1 or 0)
|
||||
.. " playerInCombat=" .. tostring((type(UnitAffectingCombat) == "function" and UnitAffectingCombat("player")) and 1 or 0))
|
||||
end
|
||||
if event == "VARIABLES_LOADED" then
|
||||
local saved = AutoStrip_GetSaved()
|
||||
AutoStrip_Trace("VARIABLES_LOADED saved.autostrip=" .. tostring(saved["autostrip"] and 1 or 0)
|
||||
@@ -318,9 +328,11 @@ end
|
||||
|
||||
AutoStrip_Frame = CreateFrame("Frame", "MTH_AutoStripEvent")
|
||||
if AutoStrip_Frame then
|
||||
-- PLAYER_REGEN_DISABLED / PLAYER_REGEN_ENABLED are intentionally NOT registered here.
|
||||
-- They are registered only when the feature is enabled via AutoStrip_SetAutoStripToggle(true),
|
||||
-- and unregistered when it is disabled. This prevents any combat event overhead when the
|
||||
-- feature is off.
|
||||
AutoStrip_Frame:RegisterEvent("VARIABLES_LOADED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
AutoStrip_Frame:RegisterEvent("PLAYER_LOGOUT")
|
||||
AutoStrip_Frame:SetScript("OnEvent", AutoStrip_OnEvent)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
MTH_CONST = MTH_CONST or {}
|
||||
MTH_CONST.version = MTH_CONST.version or "1.4.0"
|
||||
MTH_CONST.version = MTH_CONST.version or "1.4.1"
|
||||
|
||||
MTH_CONST.WEAPON_TYPES = {
|
||||
BOWS = "Bows",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MTH = MTH or {
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
name = "MetaHunt",
|
||||
modules = {},
|
||||
config = {},
|
||||
|
||||
+26
-2
@@ -19,6 +19,30 @@ local function MTH_Profile_DeepCopy(orig)
|
||||
return copy
|
||||
end
|
||||
|
||||
-- Shallow-copy a module's saved data, skipping keys that hold large operational
|
||||
-- blobs (e.g. feedomatic's "legacy" table which mirrors FOM_Cooking, FOM_QuestFood
|
||||
-- etc.) — those are runtime migration artifacts, not user configuration settings.
|
||||
local MTH_PROFILE_SKIP_KEYS = { legacy = true, history = true }
|
||||
|
||||
local function MTH_Profile_CopyModules(src)
|
||||
if type(src) ~= "table" then return {} end
|
||||
local out = {}
|
||||
for modName, modData in src do
|
||||
if type(modData) == "table" then
|
||||
local modCopy = {}
|
||||
for k, v in modData do
|
||||
if not MTH_PROFILE_SKIP_KEYS[k] then
|
||||
modCopy[MTH_Profile_DeepCopy(k)] = MTH_Profile_DeepCopy(v)
|
||||
end
|
||||
end
|
||||
out[modName] = modCopy
|
||||
else
|
||||
out[modName] = modData
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local function MTH_Profile_EnsureStore()
|
||||
if type(MTH_SavedVariables) ~= "table" then
|
||||
MTH_SavedVariables = {}
|
||||
@@ -47,13 +71,13 @@ local function MTH_Profile_BuildSnapshot()
|
||||
-- Account-wide module option values (e.g. feedomatic)
|
||||
snap.config = (type(MTH_SavedVariables) == "table"
|
||||
and type(MTH_SavedVariables.modules) == "table")
|
||||
and MTH_Profile_DeepCopy(MTH_SavedVariables.modules)
|
||||
and MTH_Profile_CopyModules(MTH_SavedVariables.modules)
|
||||
or {}
|
||||
|
||||
-- Per-character module option values (ICU, Chronometer, AutoBuy, SmartAmmo, etc.)
|
||||
snap.charConfig = (type(MTH_CharSavedVariables) == "table"
|
||||
and type(MTH_CharSavedVariables.modules) == "table")
|
||||
and MTH_Profile_DeepCopy(MTH_CharSavedVariables.modules)
|
||||
and MTH_Profile_CopyModules(MTH_CharSavedVariables.modules)
|
||||
or {}
|
||||
|
||||
-- Per-character module enabled/disabled states
|
||||
|
||||
@@ -221,8 +221,8 @@ end
|
||||
|
||||
function VC:ResetPublishDelay()
|
||||
local now = VC_GetTimeNow()
|
||||
if self.lastPublishedAt and (now - self.lastPublishedAt) < 600 then
|
||||
return -- 10-minute cooldown between publishes
|
||||
if self.lastPublishedAt and (now - self.lastPublishedAt) < 3600 then
|
||||
return -- 1-hour cooldown between publishes
|
||||
end
|
||||
self.nextPublishAt = now + math.random(10, 20)
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_AutoBuy = {
|
||||
name = "autobuy",
|
||||
enabled = false,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"MERCHANT_SHOW",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_AutoQuest = {
|
||||
name = "autoquest",
|
||||
enabled = false,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"GOSSIP_SHOW",
|
||||
"QUEST_GREETING",
|
||||
|
||||
@@ -40,10 +40,13 @@ function MTH_ChronometerHunterInstallData(engine)
|
||||
engine:AddTimer(engine.SPELL, BS["Wyvern Sting"], 12, 1, 0, 0, { gr = 2, cr = "MAROON", rc = true })
|
||||
engine:AddTimer(engine.SPELL, BS["Feed Pet"], 20, 0, 0, 0, { cr = "MAROON" })
|
||||
|
||||
engine:AddTimer(engine.EVENT, BS["Explosive Trap Effect"], 20, 1, 0, 1, { gr = 1, cr = "ORANGE", a = 1, xn = BS["Explosive Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Freezing Trap Effect"], 10, 1, 0, 1, { gr = 1, cr = "CYAN", a = 1, d = { rs = 5, tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Freezing Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Frost Trap Aura"], 30, 0, 0, 0, { gr = 1, cr = "CYAN", a = 1, d = { tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Frost Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Immolation Trap Effect"], 15, 1, 0, 1, { gr = 1, cr = "ORANGE", a = 1, xn = BS["Immolation Trap"] })
|
||||
-- Trap effects: no "a=1" here — primed by the SPELL timer's "ea" chain (cast hook sets timer.v
|
||||
-- and timer.t). Using "a=1" would trigger on any hunter's affliction message since
|
||||
-- CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS never embeds a caster name.
|
||||
engine:AddTimer(engine.EVENT, BS["Explosive Trap Effect"], 20, 1, 0, 1, { gr = 1, cr = "ORANGE", xn = BS["Explosive Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Freezing Trap Effect"], 10, 1, 0, 1, { gr = 1, cr = "CYAN", d = { rs = 5, tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Freezing Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Frost Trap Aura"], 30, 0, 0, 0, { gr = 1, cr = "CYAN", d = { tn = BS["Clever Traps"], tb = 0.15, tp = 1 }, xn = BS["Frost Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Immolation Trap Effect"], 15, 1, 0, 1, { gr = 1, cr = "ORANGE", xn = BS["Immolation Trap"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Concussive Shot"], 3, 1, 0, 0, { a = 1, cr = "BLUE", xn = BS["Concussive Shot"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Improved Wing Clip"], 5, 1, 0, 0, { a = 1, cr = "MAROON", xn = BS["Wing Clip"] })
|
||||
engine:AddTimer(engine.EVENT, BS["Lock and Load"], 10, 0, 1, 1, { a = 1, cr = "MAROON", tx = "Interface\\Icons\\ability_hunter_lockandload" }) -- 10s (tooltip confirmed; expires on Aimed Shot cast)
|
||||
|
||||
@@ -580,14 +580,18 @@ function Chronometer:OnEnable()
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_AURA_GONE_SELF", function(event, info) self:SPELL_FADE(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_AURA_GONE_OTHER", function(event, info) self:SPELL_FADE(event, info) end)
|
||||
|
||||
-- Registered events:
|
||||
-- SELF_BUFFS / SELF_DAMAGE → our own procs & self-damage (source == ParserLib_SELF confirmed)
|
||||
-- CREATURE_DAMAGE → DOT ticks on creatures ("from your X" embeds source; filtered in SPELL_PERIODIC)
|
||||
-- CREATURE_BUFFS → debuff APPLICATION on creatures ("X is afflicted by Y"; no source embedded).
|
||||
-- Needed for non-ticking debuffs: Poisonous/Enchanted Ammunition, Piercing Shot.
|
||||
-- Foreign-bar risk is mitigated in SPELL_PERIODIC by requiring victim == target
|
||||
-- when source is nil and no confirmed cast record exists.
|
||||
-- FRIENDLYPLAYER_*, HOSTILEPLAYER_* are other players' events → intentionally NOT registered.
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
self.parser:RegisterEvent(PARSER_OWNER, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE", function(event, info) self:SPELL_PERIODIC(event, info) end)
|
||||
|
||||
local enableRoM = false
|
||||
for _, timer in pairs(self.timers[self.SPELL] or {}) do
|
||||
@@ -1274,11 +1278,20 @@ end
|
||||
function Chronometer:SPELL_PERIODIC(event, info)
|
||||
local aura, rank, unit, isgain
|
||||
|
||||
-- Ignore events not caused by the player (e.g. other players' DOTs/traps nearby)
|
||||
-- Primary filter: explicit non-self source → always ignore (other player's confirmed event)
|
||||
if info.source and info.source ~= ParserLib_SELF then return end
|
||||
|
||||
-- Secondary filter: creature/friendly periodic events do NOT embed a caster name,
|
||||
-- so info.source is nil even for other players' effects. Track whether this event
|
||||
-- was provably ours (SELF_BUFFS / SELF_DAMAGE events give source == ParserLib_SELF).
|
||||
local sourceIsConfirmedSelf = (info.source == ParserLib_SELF)
|
||||
|
||||
if info.type == "buff" then
|
||||
isgain = 1
|
||||
-- Buff gained by someone other than self with no source confirmation → another player's proc
|
||||
if not sourceIsConfirmedSelf and info.victim ~= nil and info.victim ~= ParserLib_SELF then
|
||||
return
|
||||
end
|
||||
elseif info.type == "debuff" then
|
||||
isgain = nil
|
||||
elseif not info.isDOT then
|
||||
@@ -1306,7 +1319,27 @@ function Chronometer:SPELL_PERIODIC(event, info)
|
||||
if timer.k.t then
|
||||
if not unit then unit = UnitName("player") end
|
||||
if timer.k.s then
|
||||
if timer.t and timer.t ~= unit then return end
|
||||
-- Selforselect: four-tier confirmation.
|
||||
-- 1. Confirmed cast record (timer.t set by CastSpell hook): require target match.
|
||||
-- 2. Confirmed self source (SELF_BUFFS / SELF_DAMAGE events, source == SELF): accept.
|
||||
-- 3. Cast-window confirmed (timer.v fresh, timer.t nil): untargeted spells like traps
|
||||
-- where the caster is known but the trigger victim cannot be predicted in advance.
|
||||
-- Accept unconditionally — the mob that walked into the trap may not be our target.
|
||||
-- 4. Source unconfirmed AND no cast record (CREATURE_BUFFS affliction messages never
|
||||
-- embed a caster name): fall back to target-check. This lets non-ticking debuffs
|
||||
-- (Poisonous Ammo, Enchanted Ammo, Piercing Shot…) show when applied to our current
|
||||
-- target, while blocking the same debuff on a mob we are NOT targeting (i.e. another
|
||||
-- player's debuff on a different dummy).
|
||||
if timer.t then
|
||||
if timer.t ~= unit then return end
|
||||
elseif sourceIsConfirmedSelf then
|
||||
-- source confirmed → accept unconditionally
|
||||
elseif timer.v and timer.v > GetTime() then
|
||||
-- cast-window confirmed, timer.t nil → untargeted cast (e.g. trap placed on ground)
|
||||
-- victim unknown at cast time; accept whatever mob triggered it
|
||||
elseif not UnitExists("target") or unit ~= UnitName("target") then
|
||||
return
|
||||
end
|
||||
else
|
||||
if not UnitExists("target") or unit ~= UnitName("target") then return end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local MTH_ChronometerModule = {
|
||||
name = "chronometer",
|
||||
enabled = true,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {},
|
||||
initialized = false,
|
||||
}
|
||||
|
||||
+81
-46
@@ -169,28 +169,66 @@ local function MTH_EA_GetLnLRemaining()
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Scan all player auras (buffs then debuffs) for an active ammo state.
|
||||
-- Returns the matching STATE_ORDER key, or nil if none found.
|
||||
local function MTH_EA_FindAmmoAura()
|
||||
-- Try buffs first
|
||||
-- ── Fast texture-based aura scanners (no tooltip, no pcall) ─────────────────
|
||||
-- UnitBuff("player", i) → icon texture path for buff slot i (nil = end)
|
||||
-- UnitDebuff("player", i) → icon texture path for debuff slot i (nil = end)
|
||||
-- We match by icon basename instead of buff name: zero rendering cost.
|
||||
|
||||
-- Known icon basenames (lower-case, no path prefix, no extension):
|
||||
local MTH_EA_AMMO_TEX = {
|
||||
[EXPLOSIVE] = "ability_searingarrow",
|
||||
[POISONOUS] = "ability_poisonarrow",
|
||||
[ENCHANTED] = "ability_theblackarrow",
|
||||
}
|
||||
local MTH_EA_LNL_TEX = "lockandload" -- matches "ability_hunter_lockandload"
|
||||
|
||||
local function MTH_EA_IconBasename(texturePath)
|
||||
if not texturePath then return "" end
|
||||
local s = string.lower(tostring(texturePath))
|
||||
local _, _, base = string.find(s, "([^\\]+)$")
|
||||
return base or s
|
||||
end
|
||||
|
||||
-- Scan player buffs+debuffs for an active ammo state via texture comparison.
|
||||
local function MTH_EA_FindAmmoStateByTexture()
|
||||
for i = 1, 32 do
|
||||
local name = MTH_EA_GetAuraName(false, i)
|
||||
if not name then break end
|
||||
for _, stateKey in ipairs(STATE_ORDER) do
|
||||
if name == STATE_BUFF[stateKey] then return stateKey end
|
||||
local t = UnitBuff("player", i)
|
||||
if not t then break end
|
||||
local base = MTH_EA_IconBasename(t)
|
||||
for stateKey, frag in pairs(MTH_EA_AMMO_TEX) do
|
||||
if base == frag then return stateKey end
|
||||
end
|
||||
end
|
||||
-- Fall back to debuffs ("You are afflicted by" = player debuff)
|
||||
for i = 1, 16 do
|
||||
local name = MTH_EA_GetAuraName(true, i)
|
||||
if not name then break end
|
||||
for _, stateKey in ipairs(STATE_ORDER) do
|
||||
if name == STATE_BUFF[stateKey] then return stateKey end
|
||||
local t = UnitDebuff("player", i)
|
||||
if not t then break end
|
||||
local base = MTH_EA_IconBasename(t)
|
||||
for stateKey, frag in pairs(MTH_EA_AMMO_TEX) do
|
||||
if base == frag then return stateKey end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Returns true if LnL buff is currently on the player.
|
||||
local function MTH_EA_HasLnLByTexture()
|
||||
for i = 1, 32 do
|
||||
local t = UnitBuff("player", i)
|
||||
if not t then break end
|
||||
if string.find(MTH_EA_IconBasename(t), MTH_EA_LNL_TEX, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Scan all player auras (buffs then debuffs) for an active ammo state.
|
||||
-- Returns the matching STATE_ORDER key, or nil if none found.
|
||||
-- (Delegates to the fast texture path; tooltip path kept for debug use only.)
|
||||
local function MTH_EA_FindAmmoAura()
|
||||
return MTH_EA_FindAmmoStateByTexture()
|
||||
end
|
||||
|
||||
-- Restore cycle state from active auras (survives /reload within session).
|
||||
local function MTH_EA_RecoverStateFromBuffs()
|
||||
local stateKey = MTH_EA_FindAmmoAura()
|
||||
@@ -234,6 +272,10 @@ end
|
||||
-- Combat state flag (avoids needing InCombatLockdown, which doesn't exist in 1.12)
|
||||
local inCombat = false
|
||||
|
||||
-- Throttle for PLAYER_AURAS_CHANGED: even with the fast texture path this event
|
||||
-- fires 10-50+/sec in combat, so cap processing at ~6/sec.
|
||||
local MTH_EA_AurasChangedLastTime = 0
|
||||
|
||||
-- UI frame handles — declared here so MTH_EA_RefreshVisibility (and every
|
||||
-- function defined below) all close over the SAME locals.
|
||||
local strip = nil -- root drag frame (sized to 3×1 row)
|
||||
@@ -834,47 +876,40 @@ frame:SetScript("OnEvent", function()
|
||||
|
||||
if event == "PLAYER_AURAS_CHANGED" then
|
||||
if not MTH_EA_IsEnabled() then return end
|
||||
-- Pending LnL icon capture: buff is now on the unit, do the diff.
|
||||
|
||||
-- Throttle: cap processing at ~6/sec. Chat-message handlers cover all
|
||||
-- real-time state transitions; this path is only for /reload recovery
|
||||
-- and LnL sync, so a 150 ms gate is perfectly safe.
|
||||
local now = GetTime()
|
||||
if (now - MTH_EA_AurasChangedLastTime) < 0.15 then return end
|
||||
MTH_EA_AurasChangedLastTime = now
|
||||
|
||||
-- Pending LnL icon capture (no-op stub; kept to avoid errors).
|
||||
if lnlPendingCapture then
|
||||
MTH_EA_TryCaptureNewBuffIcon()
|
||||
end
|
||||
-- ── LnL detection: always sync timer from tooltip ────────────────
|
||||
-- PLAYER_AURAS_CHANGED fires for every buff change (unrelated to LnL),
|
||||
-- so we CANNOT just reset to DURATION on each fire. Instead we read
|
||||
-- the actual remaining time from the game's own buff tooltip — this
|
||||
-- gives correct values for both initial proc AND mid-buff refresh.
|
||||
local lnlBuffIndex = nil
|
||||
for i = 1, 32 do
|
||||
local name = MTH_EA_GetAuraName(false, i)
|
||||
if not name then break end
|
||||
if string.find(name, "Lock and Load", 1, true) then
|
||||
lnlBuffIndex = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if lnlBuffIndex then
|
||||
local rem = MTH_EA_GetLnLRemaining()
|
||||
if rem and rem > 0 then
|
||||
-- Sync to game's real remaining time (handles refresh correctly too).
|
||||
|
||||
-- ── LnL sync: texture-based, zero tooltip cost ───────────────────
|
||||
-- We only SET active here (initial gain / missed chat message).
|
||||
-- LOSS is authoritative from the AURA_GONE_SELF chat handler + OnUpdate
|
||||
-- expiry, so we deliberately do NOT clear lnl.active when not found —
|
||||
-- AURAS_CHANGED fires for every unrelated buff change and a transient
|
||||
-- miss during slot reordering would prematurely kill the timer.
|
||||
if MTH_EA_HasLnLByTexture() then
|
||||
if not lnl.active then
|
||||
lnl.active = true
|
||||
lnl.expiresAt = GetTime() + rem
|
||||
elseif not lnl.active then
|
||||
-- Tooltip parse failed; first-gain fallback only.
|
||||
lnl.active = true
|
||||
lnl.expiresAt = GetTime() + lnl.DURATION
|
||||
lnl.expiresAt = now + lnl.DURATION
|
||||
end
|
||||
-- If already active and parse failed: leave expiresAt as-is.
|
||||
lnlPendingCapture = false
|
||||
end
|
||||
-- NOTE: do NOT set lnl.active=false here when the buff is not found.
|
||||
-- AURAS_CHANGED fires for every unrelated buff change and the tooltip
|
||||
-- scan can transiently miss LnL during slot reordering.
|
||||
-- Loss is handled by the "fades from you" chat handler + OnUpdate expiry.
|
||||
-- Recovery path: resync ammo state after /reload.
|
||||
|
||||
-- ── Recovery: resync ammo state after /reload ─────────────────────
|
||||
if rt.state == IDLE then
|
||||
local before = rt.state
|
||||
MTH_EA_RecoverStateFromBuffs()
|
||||
if MTH_EA_DebugMode and rt.state ~= before then
|
||||
local stateKey = MTH_EA_FindAmmoStateByTexture()
|
||||
if stateKey then
|
||||
rt.state = stateKey
|
||||
rt.expiresAt = now + CYCLE_DURATION
|
||||
rt.consumed = false
|
||||
end
|
||||
MTH_EA_UpdateUI()
|
||||
end
|
||||
|
||||
@@ -926,7 +926,7 @@ function FOM_OnEvent(event, arg1)
|
||||
end
|
||||
if (foodID) then
|
||||
FOM_LastFood = GFWUtils.ItemLink(foodID);
|
||||
GFWUtils.DebugLog("Manually fed "..FOM_LastFood);
|
||||
FOM_DebugLog("Manually fed "..FOM_LastFood);
|
||||
end
|
||||
end
|
||||
return;
|
||||
@@ -1245,31 +1245,31 @@ end
|
||||
function FOM_CanFeed()
|
||||
local petInfo = MTH_FOM_GetCorePetInfo();
|
||||
if ( not (petInfo and petInfo.liveExists) ) then
|
||||
GFWUtils.DebugLog("Can't feed; pet doesn't exist.");
|
||||
FOM_DebugLog("Can't feed; pet doesn't exist.");
|
||||
return false;
|
||||
end
|
||||
if ( tonumber(petInfo.health) and tonumber(petInfo.health) <= 0 ) then
|
||||
GFWUtils.DebugLog("Can't feed; pet is dead.");
|
||||
FOM_DebugLog("Can't feed; pet is dead.");
|
||||
return false;
|
||||
end
|
||||
if ( UnitHealth("player") <= 0 ) then
|
||||
GFWUtils.DebugLog("Can't feed; I'm dead.");
|
||||
FOM_DebugLog("Can't feed; I'm dead.");
|
||||
return false;
|
||||
end
|
||||
if ( CastingBarFrameStatusBar:IsVisible() ) then
|
||||
GFWUtils.DebugLog("Can't feed; casting a spell / tradeksill.");
|
||||
FOM_DebugLog("Can't feed; casting a spell / tradeksill.");
|
||||
return false;
|
||||
end
|
||||
if ( UnitOnTaxi("player") ) then
|
||||
GFWUtils.DebugLog("Can't feed; flying.");
|
||||
FOM_DebugLog("Can't feed; flying.");
|
||||
return false;
|
||||
end
|
||||
if ( FOM_State.InCombat ) or ( PlayerFrame.inCombat ) then
|
||||
GFWUtils.DebugLog("Can't feed; in combat.");
|
||||
FOM_DebugLog("Can't feed; in combat.");
|
||||
return false;
|
||||
end
|
||||
if ( LootFrame:IsVisible() ) then
|
||||
GFWUtils.DebugLog("Shouldn't feed; loot window is open.");
|
||||
FOM_DebugLog("Shouldn't feed; loot window is open.");
|
||||
return false;
|
||||
end
|
||||
|
||||
@@ -1290,7 +1290,7 @@ function FOM_CanFeed()
|
||||
if ( buff ~= nil) then
|
||||
for _, buffTexture in dontFeedBuffTextures do
|
||||
if ( buff == buffTexture ) then
|
||||
GFWUtils.DebugLog("Can't feed; currently, eating, drinking, or feigning death.");
|
||||
FOM_DebugLog("Can't feed; currently, eating, drinking, or feigning death.");
|
||||
return false;
|
||||
end
|
||||
end
|
||||
@@ -1303,7 +1303,7 @@ function FOM_CanFeed()
|
||||
msg = string.lower(msg);
|
||||
for _, mountName in FOM_MOUNT_NAME_SUBSTRINGS do
|
||||
if (string.find(msg, mountName)) then
|
||||
GFWUtils.DebugLog("Can't feed; mounted.");
|
||||
FOM_DebugLog("Can't feed; mounted.");
|
||||
return false;
|
||||
end
|
||||
end
|
||||
@@ -1856,13 +1856,13 @@ end
|
||||
function FOM_AddFood(diet, food)
|
||||
|
||||
if (FOM_Foods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_Foods[diet] == nil");
|
||||
FOM_DebugLog("FOM_Foods[diet] == nil");
|
||||
end
|
||||
if (FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil");
|
||||
FOM_DebugLog("FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil");
|
||||
end
|
||||
if (FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil");
|
||||
FOM_DebugLog("FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil");
|
||||
end
|
||||
if ( GFWTable.IndexOf(FOM_Foods[diet], food) == 0 ) then
|
||||
if (FOM_AddedFoods == nil) then
|
||||
@@ -1898,13 +1898,13 @@ end
|
||||
function FOM_RemoveFood(diet, food)
|
||||
|
||||
if (FOM_Foods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_Foods[diet] == nil");
|
||||
FOM_DebugLog("FOM_Foods[diet] == nil");
|
||||
end
|
||||
if (FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil");
|
||||
FOM_DebugLog("FOM_AddedFoods == nil or FOM_AddedFoods[diet] == nil");
|
||||
end
|
||||
if (FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil");
|
||||
FOM_DebugLog("FOM_RemovedFoods == nil or FOM_RemovedFoods[diet] == nil");
|
||||
end
|
||||
if ( GFWTable.IndexOf(FOM_Foods[diet], food) ~= 0 ) then
|
||||
if (FOM_RemovedFoods == nil) then
|
||||
@@ -2341,7 +2341,7 @@ function FOM_Feed(aFood, options)
|
||||
foodLevel = selectedFoodLevel,
|
||||
})
|
||||
|
||||
GFWUtils.DebugLog("Picked "..FOM_LastFood.." (bag "..foodBag..", slot "..foodItem..") for feeding.");
|
||||
FOM_DebugLog("Picked "..FOM_LastFood.." (bag "..foodBag..", slot "..foodItem..") for feeding.");
|
||||
if (FOM_Config.Debug) then
|
||||
-- don't actually feed anything, just show what we would choose
|
||||
return false;
|
||||
@@ -2708,12 +2708,12 @@ end
|
||||
function FOM_IsUsefulFood(itemID, quantity)
|
||||
local foodName = GetItemInfo(itemID);
|
||||
if (foodName == nil) then
|
||||
GFWUtils.DebugLog("Can't get info for item ID "..itemID..", assuming it's OK to eat.");
|
||||
FOM_DebugLog("Can't get info for item ID "..itemID..", assuming it's OK to eat.");
|
||||
return false;
|
||||
end
|
||||
if (FOM_Cooking and FOM_Cooking[FOM_RealmPlayer] and FOM_Cooking[FOM_RealmPlayer][itemID]) then
|
||||
if (FOM_Cooking[FOM_RealmPlayer][itemID] >= FOM_Config.SaveForCookingLevel) then
|
||||
GFWUtils.DebugLog("Skipping "..quantity.."x "..foodName.."; is good for cooking.");
|
||||
FOM_DebugLog("Skipping "..quantity.."x "..foodName.."; is good for cooking.");
|
||||
return true;
|
||||
end
|
||||
end
|
||||
@@ -2725,19 +2725,19 @@ function FOM_IsUsefulFood(itemID, quantity)
|
||||
FOM_Quantity[foodName] = FOM_Quantity[foodName] + quantity;
|
||||
end
|
||||
if (FOM_Quantity[foodName] > FOM_QuestFood[FOM_RealmPlayer][foodName]) then
|
||||
GFWUtils.DebugLog("Not skipping "..quantity.."x "..foodName.."; is needed for quest, but we have more than enough.");
|
||||
FOM_DebugLog("Not skipping "..quantity.."x "..foodName.."; is needed for quest, but we have more than enough.");
|
||||
return false;
|
||||
else
|
||||
GFWUtils.DebugLog("Skipping "..quantity.."x "..foodName.."; is needed for quest.");
|
||||
FOM_DebugLog("Skipping "..quantity.."x "..foodName.."; is needed for quest.");
|
||||
return true;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (FOM_Config.AvoidBonusFood and FOM_IsInDiet(itemID, FOM_DIET_BONUS)) then
|
||||
GFWUtils.DebugLog("Skipping "..quantity.."x "..foodName.."; has bonus effect when eaten by player.");
|
||||
FOM_DebugLog("Skipping "..quantity.."x "..foodName.."; has bonus effect when eaten by player.");
|
||||
return true;
|
||||
end
|
||||
--GFWUtils.DebugLog("Not skipping "..quantity.."x "..foodName.."; doesn't have other uses.");
|
||||
--FOM_DebugLog("Not skipping "..quantity.."x "..foodName.."; doesn't have other uses.");
|
||||
return false;
|
||||
end
|
||||
|
||||
@@ -2775,7 +2775,7 @@ function FOM_IsInDiet(food, dietList)
|
||||
diet = "";
|
||||
end
|
||||
if (FOM_Foods[diet] == nil) then
|
||||
GFWUtils.DebugLog("FOM_Foods[diet] == nil");
|
||||
FOM_DebugLog("FOM_Foods[diet] == nil");
|
||||
end
|
||||
if (FOM_RemovedFoods ~= nil and FOM_RemovedFoods[diet] ~= nil and GFWTable.IndexOf(FOM_RemovedFoods[diet], food) ~= 0) then
|
||||
return false;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_FeedOMatic = {
|
||||
name = "feedomatic",
|
||||
enabled = false,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
"MERCHANT_SHOW",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_ICU = {
|
||||
name = "icu",
|
||||
enabled = false,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
},
|
||||
|
||||
@@ -48,10 +48,25 @@ end
|
||||
local MTHSmartAmmo_InitializeHooks
|
||||
MTHSmartAmmo_EnsureHooks = nil
|
||||
|
||||
local MTH_SA_SPELL_EVENTS = {
|
||||
"START_AUTOREPEAT_SPELL",
|
||||
"STOP_AUTOREPEAT_SPELL",
|
||||
"SPELLCAST_INTERRUPTED",
|
||||
"SPELLCAST_FAILED",
|
||||
"SPELLCAST_STOP",
|
||||
"SPELLCAST_DELAYED",
|
||||
}
|
||||
|
||||
function MTHSmartAmmo_SetSmartEnabled(enabled, silent)
|
||||
local saved = MTHSmartAmmo_GetSaved()
|
||||
if enabled then
|
||||
saved["enabled"] = 1
|
||||
local evFrame = getglobal("MTH_SA_EventFrame")
|
||||
if evFrame then
|
||||
for _, ev in ipairs(MTH_SA_SPELL_EVENTS) do
|
||||
evFrame:RegisterEvent(ev)
|
||||
end
|
||||
end
|
||||
if MTHSmartAmmo_InitializeHooks then
|
||||
MTHSmartAmmo_InitializeHooks()
|
||||
end
|
||||
@@ -63,6 +78,12 @@ function MTHSmartAmmo_SetSmartEnabled(enabled, silent)
|
||||
end
|
||||
else
|
||||
saved["enabled"] = false
|
||||
local evFrame = getglobal("MTH_SA_EventFrame")
|
||||
if evFrame then
|
||||
for _, ev in ipairs(MTH_SA_SPELL_EVENTS) do
|
||||
evFrame:UnregisterEvent(ev)
|
||||
end
|
||||
end
|
||||
if not silent and DEFAULT_CHAT_FRAME then
|
||||
MTH_SA_Print("Smart Ammo Disabled.")
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ MTH_SA_MANAGED_HOOKS = true
|
||||
local MTH_SmartAmmo = {
|
||||
name = "smartammo",
|
||||
enabled = true,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
-- PLAYER_ENTERING_WORLD handled by engine's own frame
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
local MTH_Tooltips = {
|
||||
name = "tooltips",
|
||||
enabled = true,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"UPDATE_MOUSEOVER_UNIT",
|
||||
"UNIT_NAME_UPDATE",
|
||||
|
||||
@@ -86,6 +86,7 @@ ZHUNTER_TRACK_GIANTS = "Track Giants"
|
||||
ZHUNTER_TRACK_MINERALS = "Find Minerals"
|
||||
ZHUNTER_TRACK_HERBS = "Find Herbs"
|
||||
ZHUNTER_TRACK_TREASURE = "Find Treasure"
|
||||
ZHUNTER_TRACK_TREES = "Find Trees"
|
||||
|
||||
ZHUNTER_TRAP_FREEZING = "Freezing Trap"
|
||||
ZHUNTER_TRAP_FROST = "Frost Trap"
|
||||
|
||||
@@ -8,7 +8,7 @@ MTH_ZH_MANAGED_HOOKS = true
|
||||
local MTH_ZHunter = {
|
||||
name = "zhunter",
|
||||
enabled = true,
|
||||
version = "1.4.0",
|
||||
version = "1.4.1",
|
||||
events = {
|
||||
"VARIABLES_LOADED",
|
||||
-- PLAYER_ENTERING_WORLD handled by bootstrap frame + adjustment frames
|
||||
|
||||
@@ -249,7 +249,8 @@ end
|
||||
function zButtonMounts_SetupSizeAndPosition()
|
||||
local saved = zButtonMounts_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_MountsAdjust and MTH_ZH_MountsAdjust.SetScript then
|
||||
if MTH_ZH_MountsAdjust then
|
||||
MTH_ZH_MountsAdjust:UnregisterAllEvents()
|
||||
MTH_ZH_MountsAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonMounts and zButtonMounts.Hide then
|
||||
@@ -257,7 +258,9 @@ function zButtonMounts_SetupSizeAndPosition()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_MountsAdjust and MTH_ZH_MountsAdjust.SetScript then
|
||||
if MTH_ZH_MountsAdjust then
|
||||
MTH_ZH_MountsAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_MountsAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_MountsAdjust:SetScript("OnEvent", MTH_ZH_MountsAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonMounts.found or 0
|
||||
|
||||
@@ -235,7 +235,8 @@ end
|
||||
function zButtonPet_SetupSizeAndPosition()
|
||||
local saved = zButtonPet_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_PetAdjust and MTH_ZH_PetAdjust.SetScript then
|
||||
if MTH_ZH_PetAdjust then
|
||||
MTH_ZH_PetAdjust:UnregisterAllEvents()
|
||||
MTH_ZH_PetAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonPet and zButtonPet.Hide then
|
||||
@@ -243,7 +244,14 @@ function zButtonPet_SetupSizeAndPosition()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_PetAdjust and MTH_ZH_PetAdjust.SetScript then
|
||||
if MTH_ZH_PetAdjust then
|
||||
MTH_ZH_PetAdjust:RegisterEvent("UNIT_HEALTH")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("UNIT_HAPPINESS")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("UNIT_PET")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("PET_BAR_UPDATE")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_PetAdjust:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
MTH_ZH_PetAdjust:SetScript("OnEvent", MTH_ZH_PetAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonPet.found or ZHUNTER_PET_MAX
|
||||
|
||||
@@ -249,7 +249,8 @@ end
|
||||
function zButtonToys_SetupSizeAndPosition()
|
||||
local saved = zButtonToys_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_ToysAdjust and MTH_ZH_ToysAdjust.SetScript then
|
||||
if MTH_ZH_ToysAdjust then
|
||||
MTH_ZH_ToysAdjust:UnregisterAllEvents()
|
||||
MTH_ZH_ToysAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonToys and zButtonToys.Hide then
|
||||
@@ -257,7 +258,9 @@ function zButtonToys_SetupSizeAndPosition()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_ToysAdjust and MTH_ZH_ToysAdjust.SetScript then
|
||||
if MTH_ZH_ToysAdjust then
|
||||
MTH_ZH_ToysAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_ToysAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_ToysAdjust:SetScript("OnEvent", MTH_ZH_ToysAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonToys.found or 0
|
||||
|
||||
@@ -5,7 +5,7 @@ end
|
||||
local root = zButtonTrack_GetRoot()
|
||||
if not root["zButtonTrack"] then
|
||||
root["zButtonTrack"] = {}
|
||||
root["zButtonTrack"]["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
|
||||
root["zButtonTrack"]["spells"] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
||||
root["zButtonTrack"]["rows"] = 1
|
||||
root["zButtonTrack"]["horizontal"] = nil
|
||||
root["zButtonTrack"]["vertical"] = nil
|
||||
@@ -32,7 +32,8 @@ ZHunterMod_Track_Spells = {
|
||||
ZHUNTER_TRACK_GIANTS,
|
||||
ZHUNTER_TRACK_MINERALS,
|
||||
ZHUNTER_TRACK_HERBS,
|
||||
ZHUNTER_TRACK_TREASURE
|
||||
ZHUNTER_TRACK_TREASURE,
|
||||
ZHUNTER_TRACK_TREES
|
||||
}
|
||||
|
||||
local ZHUNTER_TRACK_MAX = table.getn(ZHunterMod_Track_Spells)
|
||||
@@ -311,7 +312,8 @@ function zButtonTrack_SetupSizeAndPosition()
|
||||
zButtonTrack_EnsureConfig()
|
||||
local saved = zButtonTrack_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_TrackAdjust and MTH_ZH_TrackAdjust.SetScript then
|
||||
if MTH_ZH_TrackAdjust then
|
||||
MTH_ZH_TrackAdjust:UnregisterAllEvents()
|
||||
MTH_ZH_TrackAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonTrack and zButtonTrack.Hide then
|
||||
@@ -319,7 +321,12 @@ function zButtonTrack_SetupSizeAndPosition()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_TrackAdjust and MTH_ZH_TrackAdjust.SetScript then
|
||||
if MTH_ZH_TrackAdjust then
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("MINIMAP_UPDATE_TRACKING")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
MTH_ZH_TrackAdjust:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
MTH_ZH_TrackAdjust:SetScript("OnEvent", MTH_ZH_TrackAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonTrack.found or ZHUNTER_TRACK_MAX
|
||||
|
||||
@@ -154,7 +154,8 @@ function zButtonTrap_SetupSizeAndPosition()
|
||||
zButtonTrap_EnsureConfig()
|
||||
local saved = zButtonTrap_GetSaved()
|
||||
if saved["enabled"] == false or saved["enabled"] == 0 then
|
||||
if MTH_ZH_TrapAdjust and MTH_ZH_TrapAdjust.SetScript then
|
||||
if MTH_ZH_TrapAdjust then
|
||||
MTH_ZH_TrapAdjust:UnregisterAllEvents()
|
||||
MTH_ZH_TrapAdjust:SetScript("OnEvent", nil)
|
||||
end
|
||||
if zButtonTrap and zButtonTrap.Hide then
|
||||
@@ -162,7 +163,12 @@ function zButtonTrap_SetupSizeAndPosition()
|
||||
end
|
||||
return
|
||||
end
|
||||
if MTH_ZH_TrapAdjust and MTH_ZH_TrapAdjust.SetScript then
|
||||
if MTH_ZH_TrapAdjust then
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("SPELLS_CHANGED")
|
||||
MTH_ZH_TrapAdjust:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||
MTH_ZH_TrapAdjust:SetScript("OnEvent", MTH_ZH_TrapAdjust_OnEvent)
|
||||
end
|
||||
local displayCount = zButtonTrap.found or ZHUNTER_TRAP_MAX
|
||||
|
||||
Reference in New Issue
Block a user